[apparmor] [PATCH v2 28/42] parser: Finalize the aa_kernel_interface API

Tyler Hicks tyhicks at canonical.com
Fri Mar 6 21:48:44 UTC 2015


Create new, ref, and unref functions for aa_kernel_interface. The "new"
function allows for the caller to pass in an aa_features object that is
then used to check if the kernel supports set load operations.
Additionally, the "new" function allows for the apparmorfs path to be
discovered once instead of during every policy load.

Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
Acked-by: John Johansen <john.johansen at canonical.com>
---
 parser/kernel_interface.c | 184 +++++++++++++++++++++++++++++++++++-----------
 parser/kernel_interface.h |  32 ++++++--
 parser/parser.h           |  12 ++-
 parser/parser_common.c    |   1 -
 parser/parser_interface.c |  22 ++++--
 parser/parser_main.c      |  62 ++++++++--------
 parser/parser_policy.c    |  16 ++--
 7 files changed, 226 insertions(+), 103 deletions(-)

diff --git a/parser/kernel_interface.c b/parser/kernel_interface.c
index 9d7406e..c046e0e 100644
--- a/parser/kernel_interface.c
+++ b/parser/kernel_interface.c
@@ -32,13 +32,19 @@
 
 #define DEFAULT_APPARMORFS "/sys/kernel/security/apparmor"
 
+struct aa_kernel_interface {
+	unsigned int ref_count;
+	bool supports_setload;
+	int dirfd;
+};
+
 /**
- * aa_find_iface_dir - find where the apparmor interface is located
+ * find_iface_dir - find where the apparmor interface is located
  * @dir - RETURNs: stored location of interface director
  *
  * Returns: 0 on success, -1 with errno set if there is an error
  */
-int aa_find_iface_dir(char **dir)
+static int find_iface_dir(char **dir)
 {
 	if (aa_find_mountpoint(dir) == -1) {
 		struct stat buf;
@@ -54,22 +60,6 @@ int aa_find_iface_dir(char **dir)
 	return 0;
 }
 
-/**
- * open_iface_dir - open the apparmor interface dir
- *
- * Returns: opened file descriptor, or -1 with errno on error
- */
-static int open_iface_dir(void)
-{
-	autofree char *dir = NULL;
-
-	if (aa_find_iface_dir(&dir) == -1)
-		return -1;
-
-	return open(dir, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
-}
-
-
 /* bleah the kernel should just loop and do multiple load, but to support
  * older systems we need to do this
  */
@@ -148,24 +138,22 @@ static int write_policy_buffer(int fd, int atomic,
 #define AA_IFACE_FILE_REMOVE	".remove"
 #define AA_IFACE_FILE_REPLACE	".replace"
 
-static int write_policy_buffer_to_iface(const char *iface_file,
+static int write_policy_buffer_to_iface(aa_kernel_interface *kernel_interface,
+					const char *iface_file,
 					const char *buffer, size_t size)
 {
-	autoclose int dirfd = -1;
 	autoclose int fd = -1;
 
-	dirfd = open_iface_dir();
-	if (dirfd == -1)
-		return -1;
-
-	fd = openat(dirfd, iface_file, O_WRONLY | O_CLOEXEC);
+	fd = openat(kernel_interface->dirfd, iface_file, O_WRONLY | O_CLOEXEC);
 	if (fd == -1)
 		return -1;
 
-	return write_policy_buffer(fd, kernel_supports_setload, buffer, size);
+	return write_policy_buffer(fd, kernel_interface->supports_setload,
+				   buffer, size);
 }
 
-static int write_policy_fd_to_iface(const char *iface_file, int fd)
+static int write_policy_fd_to_iface(aa_kernel_interface *kernel_interface,
+				    const char *iface_file, int fd)
 {
 	autofree char *buffer = NULL;
 	int size = 0, asize = 0, rsize;
@@ -190,10 +178,12 @@ static int write_policy_fd_to_iface(const char *iface_file, int fd)
 	if (rsize == -1)
 		return -1;
 
-	return write_policy_buffer_to_iface(iface_file, buffer, size);
+	return write_policy_buffer_to_iface(kernel_interface, iface_file,
+					    buffer, size);
 }
 
-static int write_policy_file_to_iface(const char *iface_file, const char *path)
+static int write_policy_file_to_iface(aa_kernel_interface *kernel_interface,
+				      const char *iface_file, const char *path)
 {
 	autoclose int fd;
 
@@ -201,87 +191,193 @@ static int write_policy_file_to_iface(const char *iface_file, const char *path)
 	if (fd == -1)
 		return -1;
 
-	return write_policy_fd_to_iface(iface_file, fd);
+	return write_policy_fd_to_iface(kernel_interface, iface_file, fd);
+}
+
+/**
+ * aa_kernel_interface_new - create a new kernel_interface from an optional path
+ * @kernel_interface: will point to the address of an allocated and initialized
+ *                    aa_kernel_interface object upon success
+ * @kernel_features: features representing the currently running kernel
+ * @apparmorfs: path to the apparmor directory of the mounted securityfs (can
+ *              be NULL and the path will be auto discovered)
+ *
+ * Returns: 0 on success, -1 on error with errnot set and *@kernel_interface
+ *          pointing to NULL
+ */
+int aa_kernel_interface_new(aa_kernel_interface **kernel_interface,
+			    aa_features *kernel_features,
+			    const char *apparmorfs)
+{
+	aa_kernel_interface *ki;
+	autofree char *alloced_apparmorfs = NULL;
+	char set_load[] = "policy/set_load";
+
+	*kernel_interface = NULL;
+
+	ki = (aa_kernel_interface *) calloc(1, sizeof(*ki));
+	if (!ki) {
+		errno = ENOMEM;
+		return -1;
+	}
+	aa_kernel_interface_ref(ki);
+	ki->dirfd = -1;
+
+	ki->supports_setload = kernel_features ?
+			       aa_features_supports(kernel_features, set_load) :
+			       false;
+
+	if (!apparmorfs) {
+		if (find_iface_dir(&alloced_apparmorfs) == -1) {
+			int save = errno;
+
+			alloced_apparmorfs = NULL;
+			aa_kernel_interface_unref(ki);
+			errno = save;
+			return -1;
+		}
+		/* alloced_apparmorfs will be autofree'ed */
+		apparmorfs = alloced_apparmorfs;
+	}
+
+	ki->dirfd = open(apparmorfs, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
+	if (ki->dirfd < 0) {
+		int save = errno;
+
+		aa_kernel_interface_unref(ki);
+		errno = save;
+		return -1;
+	}
+
+	*kernel_interface = ki;
+
+	return 0;
+}
+
+/**
+ * aa_kernel_interface_ref - increments the ref count of a kernel_interface
+ * @kernel_interface: the kernel_interface
+ *
+ * Returns: the kernel_interface
+ */
+aa_kernel_interface *aa_kernel_interface_ref(aa_kernel_interface *kernel_interface)
+{
+	atomic_inc(&kernel_interface->ref_count);
+	return kernel_interface;
+}
+
+/**
+ * aa_kernel_interface_unref - decrements the ref count and frees the kernel_interface when 0
+ * @kernel_interface: the kernel_interface (can be NULL)
+ */
+void aa_kernel_interface_unref(aa_kernel_interface *kernel_interface)
+{
+	if (kernel_interface &&
+	    atomic_dec_and_test(&kernel_interface->ref_count)) {
+		close(kernel_interface->dirfd);
+		free(kernel_interface);
+	}
 }
 
 /**
  * aa_kernel_interface_load_policy - load a policy into the kernel
+ * @kernel_interface: valid aa_kernel_interface
  * @buffer: a buffer containing a policy
  * @size: the size of the buffer
  *
  * Returns: 0 on success, -1 on error with errno set
  */
-int aa_kernel_interface_load_policy(const char *buffer, size_t size)
+int aa_kernel_interface_load_policy(aa_kernel_interface *kernel_interface,
+				    const char *buffer, size_t size)
 {
-	return write_policy_buffer_to_iface(AA_IFACE_FILE_LOAD, buffer, size);
+	return write_policy_buffer_to_iface(kernel_interface,
+					    AA_IFACE_FILE_LOAD, buffer, size);
 }
 
 /**
  * aa_kernel_interface_load_policy_from_file - load a policy into the kernel
+ * @kernel_interface: valid aa_kernel_interface
  * @path: path to a policy binary
  *
  * Returns: 0 on success, -1 on error with errno set
  */
-int aa_kernel_interface_load_policy_from_file(const char *path)
+int aa_kernel_interface_load_policy_from_file(aa_kernel_interface *kernel_interface,
+					      const char *path)
 {
-	return write_policy_file_to_iface(AA_IFACE_FILE_LOAD, path);
+	return write_policy_file_to_iface(kernel_interface, AA_IFACE_FILE_LOAD,
+					  path);
 }
 
 /**
  * aa_kernel_interface_load_policy_from_fd - load a policy into the kernel
+ * @kernel_interface: valid aa_kernel_interface
  * @fd: a pre-opened, readable file descriptor at the correct offset
  *
  * Returns: 0 on success, -1 on error with errno set
  */
-int aa_kernel_interface_load_policy_from_fd(int fd)
+int aa_kernel_interface_load_policy_from_fd(aa_kernel_interface *kernel_interface,
+					    int fd)
 {
-	return write_policy_fd_to_iface(AA_IFACE_FILE_LOAD, fd);
+	return write_policy_fd_to_iface(kernel_interface, AA_IFACE_FILE_LOAD,
+					fd);
 }
 
 /**
  * aa_kernel_interface_replace_policy - replace a policy in the kernel
+ * @kernel_interface: valid aa_kernel_interface
  * @buffer: a buffer containing a policy
  * @size: the size of the buffer
  *
  * Returns: 0 on success, -1 on error with errno set
  */
-int aa_kernel_interface_replace_policy(const char *buffer, size_t size)
+int aa_kernel_interface_replace_policy(aa_kernel_interface *kernel_interface,
+				       const char *buffer, size_t size)
 {
-	return write_policy_buffer_to_iface(AA_IFACE_FILE_REPLACE,
+	return write_policy_buffer_to_iface(kernel_interface,
+					    AA_IFACE_FILE_REPLACE,
 					    buffer, size);
 }
 
 /**
  * aa_kernel_interface_replace_policy_from_file - replace a policy in the kernel
+ * @kernel_interface: valid aa_kernel_interface
  * @path: path to a policy binary
  *
  * Returns: 0 on success, -1 on error with errno set
  */
-int aa_kernel_interface_replace_policy_from_file(const char *path)
+int aa_kernel_interface_replace_policy_from_file(aa_kernel_interface *kernel_interface,
+						 const char *path)
 {
-	return write_policy_file_to_iface(AA_IFACE_FILE_REPLACE, path);
+	return write_policy_file_to_iface(kernel_interface,
+					  AA_IFACE_FILE_REPLACE, path);
 }
 
 /**
  * aa_kernel_interface_replace_policy_from_fd - replace a policy in the kernel
+ * @kernel_interface: valid aa_kernel_interface
  * @fd: a pre-opened, readable file descriptor at the correct offset
  *
  * Returns: 0 on success, -1 on error with errno set
  */
-int aa_kernel_interface_replace_policy_from_fd(int fd)
+int aa_kernel_interface_replace_policy_from_fd(aa_kernel_interface *kernel_interface,
+					       int fd)
 {
-	return write_policy_fd_to_iface(AA_IFACE_FILE_REPLACE, fd);
+	return write_policy_fd_to_iface(kernel_interface, AA_IFACE_FILE_REPLACE,
+					fd);
 }
 
 /**
  * aa_kernel_interface_remove_policy - remove a policy from the kernel
+ * @kernel_interface: valid aa_kernel_interface
  * @fqname: nul-terminated fully qualified name of the policy to remove
  *
  * Returns: 0 on success, -1 on error with errno set
  */
-int aa_kernel_interface_remove_policy(const char *fqname)
+int aa_kernel_interface_remove_policy(aa_kernel_interface *kernel_interface,
+				      const char *fqname)
 {
-	return write_policy_buffer_to_iface(AA_IFACE_FILE_REMOVE,
+	return write_policy_buffer_to_iface(kernel_interface,
+					    AA_IFACE_FILE_REMOVE,
 					    fqname, strlen(fqname) + 1);
 }
 
diff --git a/parser/kernel_interface.h b/parser/kernel_interface.h
index 52e537e..6dcd3ca 100644
--- a/parser/kernel_interface.h
+++ b/parser/kernel_interface.h
@@ -19,14 +19,30 @@
 #ifndef __AA_KERNEL_INTERFACE_H
 #define __AA_KERNEL_INTERFACE_H
 
-int aa_find_iface_dir(char **dir);
-int aa_kernel_interface_load_policy(const char *buffer, size_t size);
-int aa_kernel_interface_load_policy_from_file(const char *path);
-int aa_kernel_interface_load_policy_from_fd(int fd);
-int aa_kernel_interface_replace_policy(const char *buffer, size_t size);
-int aa_kernel_interface_replace_policy_from_file(const char *path);
-int aa_kernel_interface_replace_policy_from_fd(int fd);
-int aa_kernel_interface_remove_policy(const char *fqname);
+#include "features.h"
+
+typedef struct aa_kernel_interface aa_kernel_interface;
+
+int aa_kernel_interface_new(aa_kernel_interface **kernel_interface,
+			    aa_features *kernel_features,
+			    const char *apparmorfs);
+aa_kernel_interface *aa_kernel_interface_ref(aa_kernel_interface *kernel_interface);
+void aa_kernel_interface_unref(aa_kernel_interface *kernel_interface);
+
+int aa_kernel_interface_load_policy(aa_kernel_interface *kernel_interface,
+				    const char *buffer, size_t size);
+int aa_kernel_interface_load_policy_from_file(aa_kernel_interface *kernel_interface,
+					      const char *path);
+int aa_kernel_interface_load_policy_from_fd(aa_kernel_interface *kernel_interface,
+					    int fd);
+int aa_kernel_interface_replace_policy(aa_kernel_interface *kernel_interface,
+				       const char *buffer, size_t size);
+int aa_kernel_interface_replace_policy_from_file(aa_kernel_interface *kernel_interface,
+						 const char *path);
+int aa_kernel_interface_replace_policy_from_fd(aa_kernel_interface *kernel_interface,
+					       int fd);
+int aa_kernel_interface_remove_policy(aa_kernel_interface *kernel_interface,
+				      const char *fqname);
 int aa_kernel_interface_write_policy(int fd, const char *buffer, size_t size);
 
 #endif /* __AA_KERNEL_INTERFACE_H */
diff --git a/parser/parser.h b/parser/parser.h
index b9fc018..50f5bb0 100644
--- a/parser/parser.h
+++ b/parser/parser.h
@@ -33,6 +33,7 @@
 #include "immunix.h"
 #include "libapparmor_re/apparmor_re.h"
 #include "libapparmor_re/aare_rules.h"
+#include "kernel_interface.h"
 
 #include <string>
 
@@ -308,7 +309,6 @@ extern int option;
 extern int current_lineno;
 extern dfaflags_t dfaflags;
 extern const char *progname;
-extern char *subdomainbase;
 extern char *profilename;
 extern char *profile_ns;
 extern char *current_filename;
@@ -427,7 +427,8 @@ extern void free_aliases(void);
 extern int profile_merge_rules(Profile *prof);
 
 /* parser_interface.c */
-extern int load_profile(int option, Profile *prof, int cache_fd);
+extern int load_profile(int option, aa_kernel_interface *kernel_interface,
+			Profile *prof, int cache_fd);
 extern void sd_serialize_profile(std::ostringstream &buf, Profile *prof,
 				int flatten);
 extern int sd_load_buffer(int option, char *buffer, int size);
@@ -448,9 +449,12 @@ extern int process_profile_policydb(Profile *prof);
 extern int post_merge_rules(void);
 extern int merge_hat_rules(Profile *prof);
 extern Profile *merge_policy(Profile *a, Profile *b);
-extern int load_policy(int option, int cache_fd);
+extern int load_policy(int option, aa_kernel_interface *kernel_interface,
+		       int cache_fd);
 extern int load_hats(std::ostringstream &buf, Profile *prof);
-extern int load_flattened_hats(Profile *prof, int option, int cache_fd);
+extern int load_flattened_hats(Profile *prof, int option,
+			       aa_kernel_interface *kernel_interface,
+			       int cache_fd);
 extern void dump_policy_hats(Profile *prof);
 extern void dump_policy_names(void);
 void dump_policy(void);
diff --git a/parser/parser_common.c b/parser/parser_common.c
index b41e3ce..af77cb8 100644
--- a/parser/parser_common.c
+++ b/parser/parser_common.c
@@ -82,7 +82,6 @@ int option = OPTION_ADD;
 dfaflags_t dfaflags = (dfaflags_t)(DFA_CONTROL_TREE_NORMAL | DFA_CONTROL_TREE_SIMPLE | DFA_CONTROL_MINIMIZE | DFA_CONTROL_DIFF_ENCODE);
 dfaflags_t warnflags = 0;
 
-char *subdomainbase = NULL;
 const char *progname = __FILE__;
 char *profile_ns = NULL;
 char *profilename = NULL;
diff --git a/parser/parser_interface.c b/parser/parser_interface.c
index fef26bf..f864cd8 100644
--- a/parser/parser_interface.c
+++ b/parser/parser_interface.c
@@ -42,7 +42,8 @@
 #define SD_STR_LEN (sizeof(u16))
 
 
-int __sd_serialize_profile(int option, Profile *prof, int cache_fd);
+int __sd_serialize_profile(int option, aa_kernel_interface *kernel_interface,
+			   Profile *prof, int cache_fd);
 
 static void print_error(int error)
 {
@@ -83,13 +84,14 @@ static void print_error(int error)
 	}
 }
 
-int load_profile(int option, Profile *prof, int cache_fd)
+int load_profile(int option, aa_kernel_interface *kernel_interface,
+		 Profile *prof, int cache_fd)
 {
 	int retval = 0;
 	int error = 0;
 
 	PDEBUG("Serializing policy for %s.\n", prof->name);
-	retval = __sd_serialize_profile(option, prof, cache_fd);
+	retval = __sd_serialize_profile(option, kernel_interface, prof, cache_fd);
 
 	if (retval < 0) {
 		error = retval;	/* yeah, we'll just report the last error */
@@ -475,7 +477,8 @@ void sd_serialize_top_profile(std::ostringstream &buf, Profile *profile)
 	sd_serialize_profile(buf, profile, profile->parent ? 1 : 0);
 }
 
-int __sd_serialize_profile(int option, Profile *prof, int cache_fd)
+int __sd_serialize_profile(int option, aa_kernel_interface *kernel_interface,
+			   Profile *prof, int cache_fd)
 {
 	autoclose int fd = -1;
 	int error, size, wsize;
@@ -514,7 +517,8 @@ int __sd_serialize_profile(int option, Profile *prof, int cache_fd)
 
 	if (option == OPTION_REMOVE) {
 		if (kernel_load) {
-			if (aa_kernel_interface_remove_policy(prof->fqname().c_str()) == -1)
+			if (aa_kernel_interface_remove_policy(kernel_interface,
+							      prof->fqname().c_str()) == -1)
 				error = -errno;
 		}
 	} else {
@@ -526,10 +530,12 @@ int __sd_serialize_profile(int option, Profile *prof, int cache_fd)
 		size = (long) work_area.tellp();
 		if (kernel_load) {
 			if (option == OPTION_ADD &&
-			    aa_kernel_interface_load_policy(tmp.c_str(), size) == -1) {
+			    aa_kernel_interface_load_policy(kernel_interface,
+							    tmp.c_str(), size) == -1) {
 				error = -errno;
 			} else if (option == OPTION_REPLACE &&
-				   aa_kernel_interface_replace_policy(tmp.c_str(), size) == -1) {
+				   aa_kernel_interface_replace_policy(kernel_interface,
+								      tmp.c_str(), size) == -1) {
 				error = -errno;
 			}
 		} else if ((option == OPTION_STDOUT || option == OPTION_OFILE) &&
@@ -550,7 +556,7 @@ int __sd_serialize_profile(int option, Profile *prof, int cache_fd)
 	}
 
 	if (!prof->hat_table.empty() && option != OPTION_REMOVE) {
-		if (load_flattened_hats(prof, option, cache_fd) == 0)
+		if (load_flattened_hats(prof, option, kernel_interface, cache_fd) == 0)
 			return 0;
 	}
 
diff --git a/parser/parser_main.c b/parser/parser_main.c
index 1c4823a..b230a91 100644
--- a/parser/parser_main.c
+++ b/parser/parser_main.c
@@ -80,6 +80,7 @@ int mru_skip_cache = 1;
 int debug_cache = 0;
 struct timespec mru_tstamp;
 
+static char *apparmorfs = NULL;
 static char *cacheloc = NULL;
 
 static aa_features *features = NULL;
@@ -362,7 +363,7 @@ static int process_arg(int c, char *optarg)
 		}
 		break;
 	case 'f':
-		subdomainbase = strndup(optarg, PATH_MAX);
+		apparmorfs = strndup(optarg, PATH_MAX);
 		break;
 	case 'D':
 		skip_read_cache = 1;
@@ -517,19 +518,6 @@ static int process_config_file(const char *name)
 	return 1;
 }
 
-
-int find_subdomainfs_mountpoint(void)
-{
-	if (aa_find_iface_dir(&subdomainbase) == -1) {
-		PERROR(_("Warning: unable to find a suitable fs in %s, is it "
-			 "mounted?\nUse --subdomainfs to override.\n"),
-		       MOUNTED_FS);
-		return false;
-	}
-
-	return true;
-}
-
 int have_enough_privilege(void)
 {
 	uid_t uid, euid;
@@ -612,7 +600,8 @@ static void set_supported_features(void)
 		dfaflags &= ~DFA_CONTROL_DIFF_ENCODE;
 }
 
-int process_binary(int option, const char *profilename)
+int process_binary(int option, aa_kernel_interface *kernel_interface,
+		   const char *profilename)
 {
 	const char *printed_name;
 	int retval;
@@ -622,8 +611,8 @@ int process_binary(int option, const char *profilename)
 	if (kernel_load) {
 		if (option == OPTION_ADD) {
 			retval = profilename ?
-				 aa_kernel_interface_load_policy_from_file(profilename) :
-				 aa_kernel_interface_load_policy_from_fd(0);
+				 aa_kernel_interface_load_policy_from_file(kernel_interface, profilename) :
+				 aa_kernel_interface_load_policy_from_fd(kernel_interface, 0);
 			if (retval == -1) {
 				retval = errno;
 				PERROR(_("Error: Could not load profile %s: %s\n"),
@@ -632,8 +621,8 @@ int process_binary(int option, const char *profilename)
 			}
 		} else if (option == OPTION_REPLACE) {
 			retval = profilename ?
-				 aa_kernel_interface_replace_policy_from_file(profilename) :
-				 aa_kernel_interface_replace_policy_from_fd(0);
+				 aa_kernel_interface_replace_policy_from_file(kernel_interface, profilename) :
+				 aa_kernel_interface_replace_policy_from_fd(kernel_interface, 0);
 			if (retval == -1) {
 				retval = errno;
 				PERROR(_("Error: Could not replace profile %s: %s\n"),
@@ -694,7 +683,8 @@ int test_for_dir_mode(const char *basename, const char *linkdir)
 	return rc;
 }
 
-int process_profile(int option, const char *profilename, const char *cachedir)
+int process_profile(int option, aa_kernel_interface *kernel_interface,
+		    const char *profilename, const char *cachedir)
 {
 	int retval = 0;
 	autofree const char *cachename = NULL;
@@ -766,7 +756,8 @@ int process_profile(int option, const char *profilename, const char *cachedir)
 	if (cachename) {
 		/* Load a binary cache if it exists and is newest */
 		if (cache_hit(cachename)) {
-			retval = process_binary(option, cachename);
+			retval = process_binary(option, kernel_interface,
+						cachename);
 			if (!retval || skip_bad_cache_rebuild)
 				return retval;
 		}
@@ -808,7 +799,7 @@ int process_profile(int option, const char *profilename, const char *cachedir)
 	}
 
 	/* cache file generated by load_policy */
-	retval = load_policy(option, cachetmp);
+	retval = load_policy(option, kernel_interface, cachetmp);
 	if (retval == 0 && write_cache) {
 		if (cachetmp == -1) {
 			unlink(cachetmpname);
@@ -824,6 +815,7 @@ out:
 }
 
 struct dir_cb_data {
+	aa_kernel_interface *kernel_interface;
 	const char *dirname;	/* name of the parent dir */
 	const char *cachedir;	/* path to the cache sub directory */
 };
@@ -839,7 +831,8 @@ static int profile_dir_cb(DIR *dir unused, const char *name, struct stat *st,
 		autofree char *path = NULL;
 		if (asprintf(&path, "%s/%s", cb_data->dirname, name) < 0)
 			PERROR(_("Out of memory"));
-		rc = process_profile(option, path, cb_data->cachedir);
+		rc = process_profile(option, cb_data->kernel_interface, path,
+				     cb_data->cachedir);
 	}
 	return rc;
 }
@@ -855,7 +848,7 @@ static int binary_dir_cb(DIR *dir unused, const char *name, struct stat *st,
 		autofree char *path = NULL;
 		if (asprintf(&path, "%s/%s", cb_data->dirname, name) < 0)
 			PERROR(_("Out of memory"));
-		rc = process_binary(option, path);
+		rc = process_binary(option, cb_data->kernel_interface, path);
 	}
 	return rc;
 }
@@ -877,6 +870,7 @@ static void setup_flags(void)
 
 int main(int argc, char *argv[])
 {
+	aa_kernel_interface *kernel_interface = NULL;
 	aa_policy_cache *policy_cache;
 	int retval, last_error;
 	int i;
@@ -900,16 +894,18 @@ int main(int argc, char *argv[])
 		return retval;
 	}
 
-	/* Check to make sure there is an interface to load policy */
-	if (!(UNPRIVILEGED_OPS) && (subdomainbase == NULL) &&
-	    !find_subdomainfs_mountpoint()) {
-		return 1;
-	}
-
 	if (!binary_input) parse_default_paths();
 
 	setup_flags();
 
+	if (!(UNPRIVILEGED_OPS) &&
+	    aa_kernel_interface_new(&kernel_interface, features, apparmorfs) == -1) {
+		PERROR(_("Warning: unable to find a suitable fs in %s, is it "
+		       "mounted?\nUse --subdomainfs to override.\n"),
+		       MOUNTED_FS);
+		return 1;
+	}
+
 	if ((!skip_cache && (write_cache || !skip_read_cache)) ||
 	    force_clear_cache) {
 		if (!cacheloc && asprintf(&cacheloc, "%s/cache", basedir) == -1) {
@@ -988,9 +984,11 @@ int main(int argc, char *argv[])
 				       profilename);
 			}
 		} else if (binary_input) {
-			retval = process_binary(option, profilename);
+			retval = process_binary(option, kernel_interface,
+						profilename);
 		} else {
-			retval = process_profile(option, profilename, cacheloc);
+			retval = process_profile(option, kernel_interface,
+						 profilename, cacheloc);
 		}
 
 		if (profilename) free(profilename);
diff --git a/parser/parser_policy.c b/parser/parser_policy.c
index 137f9b6..0652715 100644
--- a/parser/parser_policy.c
+++ b/parser/parser_policy.c
@@ -31,6 +31,7 @@
 #include "parser.h"
 #include "profile.h"
 #include "parser_yacc.h"
+#include "kernel_interface.h"
 
 /* #define DEBUG */
 #ifdef DEBUG
@@ -220,12 +221,13 @@ static int profile_add_hat_rules(Profile *prof)
 	return 0;
 }
 
-int load_policy_list(ProfileList &list, int option, int cache_fd)
+int load_policy_list(ProfileList &list, int option,
+		     aa_kernel_interface *kernel_interface, int cache_fd)
 {
 	int res = 0;
 
 	for (ProfileList::iterator i = list.begin(); i != list.end(); i++) {
-		res = load_profile(option, *i, cache_fd);
+		res = load_profile(option, kernel_interface, *i, cache_fd);
 		if (res != 0)
 			break;
 	}
@@ -233,14 +235,16 @@ int load_policy_list(ProfileList &list, int option, int cache_fd)
 	return res;
 }
 
-int load_flattened_hats(Profile *prof, int option, int cache_fd)
+int load_flattened_hats(Profile *prof, int option,
+			aa_kernel_interface *kernel_interface, int cache_fd)
 {
-	return load_policy_list(prof->hat_table, option, cache_fd);
+	return load_policy_list(prof->hat_table, option, kernel_interface,
+				cache_fd);
 }
 
-int load_policy(int option, int cache_fd)
+int load_policy(int option, aa_kernel_interface *kernel_interface, int cache_fd)
 {
-	return load_policy_list(policy_list, option, cache_fd);
+	return load_policy_list(policy_list, option, kernel_interface, cache_fd);
 }
 
 int load_hats(std::ostringstream &buf, Profile *prof)
-- 
2.1.4




More information about the AppArmor mailing list