[apparmor] [PATCH 5/5] Function to test if apparmor support isenabled.
John Johansen
john.johansen at canonical.com
Thu Jul 21 20:38:28 UTC 2011
On 07/21/2011 12:06 PM, Seth Arnold wrote:
> I'm not sure I like a 0 return for "enabled" :)
>
heh I hate it, just following the 0 is success convention, but
perhaps we can make an exception for this function.
> if (!aa_is_enabled()) { /* enabled */ } else { /* check errno */ }
>
> The routine also makes some big assumptions about specific path names (similar to the mountpoint finder -- existence of the path /sys/kernel/security/apparmor doesn't necessarily mean it is a securityfs mount point) and a confined program's ability to use the filesystem -- EPERM should probably also be included as "AA potentially enabled and confinement forbids learning details".
>
it does, I basically copied the parsers routine and stripped it of its
subdomainfs bits and then moved you fallback to a last ditch absolute
path, to the front to short circuit the mount walk.
But I don't think that is really needed as if you can't find the
mount you shouldn't be finding a valid path anyway, and the static
variable that caches the state, will short circuit the mount walk
on subsequent calls
revised patch below
---
Function to test if apparmor support is enabled.
Signed-off-by: John Johansen <john.johansen at canonical.com>
diff --git a/libraries/libapparmor/doc/aa_find_mountpoint.pod b/libraries/libapparmor/doc/aa_find_mountpoint.pod
index 28f25f4..98fa276 100644
--- a/libraries/libapparmor/doc/aa_find_mountpoint.pod
+++ b/libraries/libapparmor/doc/aa_find_mountpoint.pod
@@ -22,24 +22,36 @@
=head1 NAME
+aa_is_enabled - determine if apparmor is available
+
aa_find_mountpoint - find where the apparmor interface filesystem is mounted
=head1 SYNOPSIS
B<#include E<lt>sys/apparmor.hE<gt>>
+B<int aa_is_enabled(void);>
+
B<int aa_find_mountpoint(char **mnt);>
Link with B<-lapparmor> when compiling.
=head1 DESCRIPTION
+The aa_is_enabled function returns true (1) if apparmor is enabled. If it
+isn't it sets the errno to reflect the reason it is not enabled and returns 0.
+
The aa_find_mountpoint function finds where the apparmor filesystem is mounted
on the system, and returns a string containing the mount path. It is the
caller's responsibility to free(3) the returned path.
=head1 RETURN VALUE
+B<aa_is_enabled>
+On success 1 is returned. On error, 0 is returned, and errno(3) is set
+appropriately.
+
+B<aa_find_mountpoint>
On success zero is returned. On error, -1 is returned, and errno(3) is set
appropriately.
@@ -47,6 +59,36 @@ appropriately.
=over 4
+B<aa_is_enabled>
+
+=item B<ENOSYS>
+
+AppArmor extensions to the system are not available.
+
+=item B<ECANCELED>
+
+AppArmor is available on the system but has been disabled at boot.
+
+=item B<ENOENT>
+
+AppArmor is available (and maybe even enforcing policy) but the interface is
+not available.
+
+=item B<ENOMEM>
+
+Insufficient memory was available.
+
+=item B<EPERM>
+
+Did not have sufficient permissions to determine if AppArmor is enabled.
+
+=item B<EACCES>
+
++Did not have sufficient permissions to determine if AppArmor is enabled.
+
+
+B<aa_find_mountpoint>
+
=item B<ENOMEM>
Insufficient memory was available.
diff --git a/libraries/libapparmor/src/apparmor.h b/libraries/libapparmor/src/apparmor.h
index 903cecd..977263d 100644
--- a/libraries/libapparmor/src/apparmor.h
+++ b/libraries/libapparmor/src/apparmor.h
@@ -21,6 +21,8 @@
__BEGIN_DECLS
/* Prototypes for apparmor state queries */
+extern int aa_is_enabled(void);
+extern int aa_is_enabled_raw(void);
extern int aa_find_mountpoint(char **mnt);
/* Prototypes for self directed domain transitions
diff --git a/libraries/libapparmor/src/kernel_interface.c b/libraries/libapparmor/src/kernel_interface.c
index 6c20645..2f75b25 100644
--- a/libraries/libapparmor/src/kernel_interface.c
+++ b/libraries/libapparmor/src/kernel_interface.c
@@ -29,6 +29,8 @@
#include <stdarg.h>
#include <mntent.h>
+#include "apparmor.h"
+
/* some non-Linux systems do not define a static value */
#ifndef PATH_MAX
# define PATH_MAX 4096
@@ -80,6 +82,70 @@ int aa_find_mountpoint(char **mnt)
return rc;
}
+/* cache the status of aa_is_disabled lookup routine */
+static int aa_state = -1;
+
+/**
+ * aa_is_enabled_raw - determine if apparmor is enabled
+ *
+ * Returns: 1 if enabled else reason it is not, or 0 on error
+ *
+ * ENOSYS - no indication apparmor is present in the system
+ * ENOENT - enabled but interface could not be found
+ * ECANCELED - disabled at boot
+ * ENOMEM - out of memory
+ */
+int aa_is_enabled_raw(void)
+{
+ int serrno, fd, rc, size;
+ char buffer[2];
+ char *mnt;
+
+ /* if the interface mountpoint is available apparmor is enabled */
+ rc = aa_find_mountpoint(&mnt);
+ if (rc == 0) {
+ free(mnt);
+ aa_state = 1;
+ return 1;
+ }
+
+ /* determine why the interface mountpoint isn't available */
+ fd = open("/sys/module/apparmor/parameters/enabled", O_RDONLY);
+ if (fd == -1) {
+ if (errno == ENOENT)
+ errno = ENOSYS;
+ return 0;
+ }
+
+ size = read(fd, &buffer, 2);
+ serrno = errno;
+ close(fd);
+ errno = serrno;
+
+ if (size > 0) {
+ if (buffer[0] == 'Y')
+ errno = ENOENT;
+ else
+ errno = ECANCELED;
+ }
+ return 0;
+}
+
+int aa_is_enabled(void)
+{
+ int rc;
+
+ if (aa_state == 1) {
+ return 1;
+ } else if (aa_state != -1) {
+ errno = aa_state;
+ return 0;
+ }
+
+ rc = aa_is_enabled_raw();
+ aa_state = errno;
+ return rc;
+}
static inline pid_t aa_gettid(void)
{
diff --git a/libraries/libapparmor/src/libapparmor.map b/libraries/libapparmor/src/libapparmor.map
index df51d01..b118372 100644
--- a/libraries/libapparmor/src/libapparmor.map
+++ b/libraries/libapparmor/src/libapparmor.map
@@ -16,6 +16,8 @@ APPARMOR_1.0 {
APPARMOR_1.1 {
global:
+ aa_is_enabled;
+ aa_is_enabled_raw;
aa_find_mountpoint;
aa_change_hat;
aa_change_hatv;
diff --git a/libraries/libapparmor/swig/SWIG/libapparmor.i b/libraries/libapparmor/swig/SWIG/libapparmor.i
index 1b6b5c7..fc22f74 100644
--- a/libraries/libapparmor/swig/SWIG/libapparmor.i
+++ b/libraries/libapparmor/swig/SWIG/libapparmor.i
@@ -13,6 +13,8 @@
* are manually inserted here
*/
+extern int aa_is_enabled(void);
+extern int aa_is_enabled_raw(void);
extern int aa_find_mountpoint(char **mnt);
extern int aa_change_hat(const char *subprofile, unsigned long magic_token);
extern int aa_change_profile(const char *profile);
More information about the AppArmor
mailing list