[apparmor] [PATCH 29/31] parser: Finalize the aa_kernel_interface API

John Johansen john.johansen at canonical.com
Thu Jan 22 18:16:33 UTC 2015


On 12/05/2014 04:22 PM, Tyler Hicks wrote:
> 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>

with note below about another patch we should do

> ---
>  parser/kernel_interface.c | 183 +++++++++++++++++++++++++++++++++++-----------
>  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, 225 insertions(+), 103 deletions(-)
> 
> diff --git a/parser/kernel_interface.c b/parser/kernel_interface.c
> index 9d7406e..fa199f7 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,192 @@ 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;
> +
> +	*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_set_load(kernel_features) :
> +			       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 c30d429..147a7d9 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;
> @@ -425,7 +425,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);
> @@ -446,9 +447,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 8e10bd4..f86d8c5 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;
> @@ -588,7 +576,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;
> @@ -598,8 +587,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"),
> @@ -608,8 +597,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"),
> @@ -670,7 +659,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;
> @@ -742,7 +732,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;
>  		}
> @@ -784,7 +775,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);
> @@ -800,6 +791,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 */
>  };
> @@ -815,7 +807,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;
>  }
> @@ -831,7 +824,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;
>  }
> @@ -853,6 +846,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;
> @@ -876,16 +870,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;
> +	}
> +
gah --subdomainfs??? this should have died a long time ago
we should deprecate --subdomainfs and add --apparmorfs option to replace it

>  	if ((!skip_cache && (write_cache || !skip_read_cache)) ||
>  	    force_clear_cache) {
>  		if (!cacheloc && asprintf(&cacheloc, "%s/cache", basedir) == -1) {
> @@ -964,9 +960,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 2c98c45..07b219b 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
> @@ -218,12 +219,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;
>  	}
> @@ -231,14 +233,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)
> 





More information about the AppArmor mailing list