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 <[email protected]>
Acked-by: John Johansen <[email protected]>

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)
> 



-- 
AppArmor mailing list
[email protected]
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor

Reply via email to