]> Git Repo - linux.git/commitdiff
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux...
authorLinus Torvalds <[email protected]>
Tue, 21 Feb 2017 20:49:56 +0000 (12:49 -0800)
committerLinus Torvalds <[email protected]>
Tue, 21 Feb 2017 20:49:56 +0000 (12:49 -0800)
Pull security layer updates from James Morris:
 "Highlights:

   - major AppArmor update: policy namespaces & lots of fixes

   - add /sys/kernel/security/lsm node for easy detection of loaded LSMs

   - SELinux cgroupfs labeling support

   - SELinux context mounts on tmpfs, ramfs, devpts within user
     namespaces

   - improved TPM 2.0 support"

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (117 commits)
  tpm: declare tpm2_get_pcr_allocation() as static
  tpm: Fix expected number of response bytes of TPM1.2 PCR Extend
  tpm xen: drop unneeded chip variable
  tpm: fix misspelled "facilitate" in module parameter description
  tpm_tis: fix the error handling of init_tis()
  KEYS: Use memzero_explicit() for secret data
  KEYS: Fix an error code in request_master_key()
  sign-file: fix build error in sign-file.c with libressl
  selinux: allow changing labels for cgroupfs
  selinux: fix off-by-one in setprocattr
  tpm: silence an array overflow warning
  tpm: fix the type of owned field in cap_t
  tpm: add securityfs support for TPM 2.0 firmware event log
  tpm: enhance read_log_of() to support Physical TPM event log
  tpm: enhance TPM 2.0 PCR extend to support multiple banks
  tpm: implement TPM 2.0 capability to get active PCR banks
  tpm: fix RC value check in tpm2_seal_trusted
  tpm_tis: fix iTPM probe via probe_itpm() function
  tpm: Begin the process to deprecate user_read_timer
  tpm: remove tpm_read_index and tpm_write_index from tpm.h
  ...

1  2 
fs/proc/base.c
kernel/exit.c
security/apparmor/include/lib.h
security/apparmor/include/policy.h

diff --combined fs/proc/base.c
index b1f7d30e96c27aa5d3e2a9abe0052e123087a448,988c5a77e8882a5583638d5b3144d7be63de68d8..3d773eb9e14476fb4035773e6666f84f813f8369
@@@ -2179,7 -2179,7 +2179,7 @@@ static const struct file_operations pro
        .llseek         = generic_file_llseek,
  };
  
 -#ifdef CONFIG_CHECKPOINT_RESTORE
 +#if defined(CONFIG_CHECKPOINT_RESTORE) && defined(CONFIG_POSIX_TIMERS)
  struct timers_private {
        struct pid *pid;
        struct task_struct *task;
@@@ -2488,6 -2488,12 +2488,12 @@@ static ssize_t proc_pid_attr_write(stru
        length = -ESRCH;
        if (!task)
                goto out_no_task;
+       /* A task may only write its own attributes. */
+       length = -EACCES;
+       if (current != task)
+               goto out;
        if (count > PAGE_SIZE)
                count = PAGE_SIZE;
  
        }
  
        /* Guard against adverse ptrace interaction */
-       length = mutex_lock_interruptible(&task->signal->cred_guard_mutex);
+       length = mutex_lock_interruptible(&current->signal->cred_guard_mutex);
        if (length < 0)
                goto out_free;
  
-       length = security_setprocattr(task,
-                                     (char*)file->f_path.dentry->d_name.name,
+       length = security_setprocattr(file->f_path.dentry->d_name.name,
                                      page, count);
-       mutex_unlock(&task->signal->cred_guard_mutex);
+       mutex_unlock(&current->signal->cred_guard_mutex);
  out_free:
        kfree(page);
  out:
@@@ -2936,7 -2941,7 +2941,7 @@@ static const struct pid_entry tgid_base
        REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
        REG("setgroups",  S_IRUGO|S_IWUSR, proc_setgroups_operations),
  #endif
 -#ifdef CONFIG_CHECKPOINT_RESTORE
 +#if defined(CONFIG_CHECKPOINT_RESTORE) && defined(CONFIG_POSIX_TIMERS)
        REG("timers",     S_IRUGO, proc_timers_operations),
  #endif
        REG("timerslack_ns", S_IRUGO|S_IWUGO, proc_pid_set_timerslack_ns_operations),
@@@ -3179,8 -3184,6 +3184,8 @@@ int proc_pid_readdir(struct file *file
             iter.tgid += 1, iter = next_tgid(ns, iter)) {
                char name[PROC_NUMBUF];
                int len;
 +
 +              cond_resched();
                if (!has_pid_permissions(ns, iter.task, 2))
                        continue;
  
diff --combined kernel/exit.c
index b67c57faa705d991f87b13e6b17bde64afea9131,60f24519057152eb49141a245ca262f2b796c765..580da79e38ee89992a93e6cb61f2c16232d580a6
@@@ -14,7 -14,6 +14,6 @@@
  #include <linux/tty.h>
  #include <linux/iocontext.h>
  #include <linux/key.h>
- #include <linux/security.h>
  #include <linux/cpu.h>
  #include <linux/acct.h>
  #include <linux/tsacct_kern.h>
@@@ -55,7 -54,6 +54,7 @@@
  #include <linux/shm.h>
  #include <linux/kcov.h>
  #include <linux/random.h>
 +#include <linux/rcuwait.h>
  
  #include <linux/uaccess.h>
  #include <asm/unistd.h>
@@@ -87,7 -85,7 +86,7 @@@ static void __exit_signal(struct task_s
        bool group_dead = thread_group_leader(tsk);
        struct sighand_struct *sighand;
        struct tty_struct *uninitialized_var(tty);
 -      cputime_t utime, stime;
 +      u64 utime, stime;
  
        sighand = rcu_dereference_check(tsk->sighand,
                                        lockdep_tasklist_lock_is_held());
@@@ -283,35 -281,6 +282,35 @@@ retry
        return task;
  }
  
 +void rcuwait_wake_up(struct rcuwait *w)
 +{
 +      struct task_struct *task;
 +
 +      rcu_read_lock();
 +
 +      /*
 +       * Order condition vs @task, such that everything prior to the load
 +       * of @task is visible. This is the condition as to why the user called
 +       * rcuwait_trywake() in the first place. Pairs with set_current_state()
 +       * barrier (A) in rcuwait_wait_event().
 +       *
 +       *    WAIT                WAKE
 +       *    [S] tsk = current   [S] cond = true
 +       *        MB (A)              MB (B)
 +       *    [L] cond            [L] tsk
 +       */
 +      smp_rmb(); /* (B) */
 +
 +      /*
 +       * Avoid using task_rcu_dereference() magic as long as we are careful,
 +       * see comment in rcuwait_wait_event() regarding ->exit_state.
 +       */
 +      task = rcu_dereference(w->task);
 +      if (task)
 +              wake_up_process(task);
 +      rcu_read_unlock();
 +}
 +
  struct task_struct *try_get_task_struct(struct task_struct **ptask)
  {
        struct task_struct *task;
@@@ -498,12 -467,12 +497,12 @@@ assign_new_owner
   * Turn us into a lazy TLB process if we
   * aren't already..
   */
 -static void exit_mm(struct task_struct *tsk)
 +static void exit_mm(void)
  {
 -      struct mm_struct *mm = tsk->mm;
 +      struct mm_struct *mm = current->mm;
        struct core_state *core_state;
  
 -      mm_release(tsk, mm);
 +      mm_release(current, mm);
        if (!mm)
                return;
        sync_mm_rss(mm);
  
                up_read(&mm->mmap_sem);
  
 -              self.task = tsk;
 +              self.task = current;
                self.next = xchg(&core_state->dumper.next, &self);
                /*
                 * Implies mb(), the result of xchg() must be visible
                        complete(&core_state->startup);
  
                for (;;) {
 -                      set_task_state(tsk, TASK_UNINTERRUPTIBLE);
 +                      set_current_state(TASK_UNINTERRUPTIBLE);
                        if (!self.task) /* see coredump_finish() */
                                break;
                        freezable_schedule();
                }
 -              __set_task_state(tsk, TASK_RUNNING);
 +              __set_current_state(TASK_RUNNING);
                down_read(&mm->mmap_sem);
        }
        atomic_inc(&mm->mm_count);
 -      BUG_ON(mm != tsk->active_mm);
 +      BUG_ON(mm != current->active_mm);
        /* more a memory barrier than a real lock */
 -      task_lock(tsk);
 -      tsk->mm = NULL;
 +      task_lock(current);
 +      current->mm = NULL;
        up_read(&mm->mmap_sem);
        enter_lazy_tlb(mm, current);
 -      task_unlock(tsk);
 +      task_unlock(current);
        mm_update_next_owner(mm);
        mmput(mm);
        if (test_thread_flag(TIF_MEMDIE))
@@@ -853,7 -822,7 +852,7 @@@ void __noreturn do_exit(long code
        tsk->exit_code = code;
        taskstats_exit(tsk, group_dead);
  
 -      exit_mm(tsk);
 +      exit_mm();
  
        if (group_dead)
                acct_process();
@@@ -1121,7 -1090,7 +1120,7 @@@ static int wait_task_zombie(struct wait
                struct signal_struct *sig = p->signal;
                struct signal_struct *psig = current->signal;
                unsigned long maxrss;
 -              cputime_t tgutime, tgstime;
 +              u64 tgutime, tgstime;
  
                /*
                 * The resource counters for the group leader are in its
@@@ -1390,7 -1359,7 +1389,7 @@@ static int wait_task_continued(struct w
   * Returns nonzero for a final return, when we have unlocked tasklist_lock.
   * Returns zero if the search for a child should continue;
   * then ->notask_error is 0 if @p is an eligible child,
-  * or another error from security_task_wait(), or still -ECHILD.
+  * or still -ECHILD.
   */
  static int wait_consider_task(struct wait_opts *wo, int ptrace,
                                struct task_struct *p)
        if (!ret)
                return ret;
  
-       ret = security_task_wait(p);
-       if (unlikely(ret < 0)) {
-               /*
-                * If we have not yet seen any eligible child,
-                * then let this error code replace -ECHILD.
-                * A permission error will give the user a clue
-                * to look for security policy problems, rather
-                * than for mysterious wait bugs.
-                */
-               if (wo->notask_error)
-                       wo->notask_error = ret;
-               return 0;
-       }
        if (unlikely(exit_state == EXIT_TRACE)) {
                /*
                 * ptrace == 0 means we are the natural parent. In this case
   * Returns nonzero for a final return, when we have unlocked tasklist_lock.
   * Returns zero if the search for a child should continue; then
   * ->notask_error is 0 if there were any eligible children,
-  * or another error from security_task_wait(), or still -ECHILD.
+  * or still -ECHILD.
   */
  static int do_wait_thread(struct wait_opts *wo, struct task_struct *tsk)
  {
index 0000000000000000000000000000000000000000,fa281c2729705af4a6a53d71c70659eef02368f1..65ff492a98079254b53cf7cf4630d1990d78e03e
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,200 +1,194 @@@
 -/* returns 0 if kref not incremented */
 -static inline int kref_get_not0(struct kref *kref)
 -{
 -      return atomic_inc_not_zero(&kref->refcount);
 -}
 -
+ /*
+  * AppArmor security module
+  *
+  * This file contains AppArmor lib definitions
+  *
+  * 2017 Canonical Ltd.
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License as
+  * published by the Free Software Foundation, version 2 of the
+  * License.
+  */
+ #ifndef __AA_LIB_H
+ #define __AA_LIB_H
+ #include <linux/slab.h>
+ #include <linux/fs.h>
+ #include "match.h"
+ /* Provide our own test for whether a write lock is held for asserts
+  * this is because on none SMP systems write_can_lock will always
+  * resolve to true, which is what you want for code making decisions
+  * based on it, but wrong for asserts checking that the lock is held
+  */
+ #ifdef CONFIG_SMP
+ #define write_is_locked(X) !write_can_lock(X)
+ #else
+ #define write_is_locked(X) (1)
+ #endif /* CONFIG_SMP */
+ /*
+  * DEBUG remains global (no per profile flag) since it is mostly used in sysctl
+  * which is not related to profile accesses.
+  */
+ #define DEBUG_ON (aa_g_debug)
+ #define dbg_printk(__fmt, __args...) pr_debug(__fmt, ##__args)
+ #define AA_DEBUG(fmt, args...)                                                \
+       do {                                                            \
+               if (DEBUG_ON)                                           \
+                       pr_debug_ratelimited("AppArmor: " fmt, ##args); \
+       } while (0)
+ #define AA_WARN(X) WARN((X), "APPARMOR WARN %s: %s\n", __func__, #X)
+ #define AA_BUG(X, args...) AA_BUG_FMT((X), "" args)
+ #ifdef CONFIG_SECURITY_APPARMOR_DEBUG_ASSERTS
+ #define AA_BUG_FMT(X, fmt, args...)                                   \
+       WARN((X), "AppArmor WARN %s: (" #X "): " fmt, __func__, ##args)
+ #else
+ #define AA_BUG_FMT(X, fmt, args...)
+ #endif
+ #define AA_ERROR(fmt, args...)                                                \
+       pr_err_ratelimited("AppArmor: " fmt, ##args)
+ /* Flag indicating whether initialization completed */
+ extern int apparmor_initialized __initdata;
+ /* fn's in lib */
+ char *aa_split_fqname(char *args, char **ns_name);
+ const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name,
+                            size_t *ns_len);
+ void aa_info_message(const char *str);
+ void *__aa_kvmalloc(size_t size, gfp_t flags);
+ static inline void *kvmalloc(size_t size)
+ {
+       return __aa_kvmalloc(size, 0);
+ }
+ static inline void *kvzalloc(size_t size)
+ {
+       return __aa_kvmalloc(size, __GFP_ZERO);
+ }
+ /**
+  * aa_strneq - compare null terminated @str to a non null terminated substring
+  * @str: a null terminated string
+  * @sub: a substring, not necessarily null terminated
+  * @len: length of @sub to compare
+  *
+  * The @str string must be full consumed for this to be considered a match
+  */
+ static inline bool aa_strneq(const char *str, const char *sub, int len)
+ {
+       return !strncmp(str, sub, len) && !str[len];
+ }
+ /**
+  * aa_dfa_null_transition - step to next state after null character
+  * @dfa: the dfa to match against
+  * @start: the state of the dfa to start matching in
+  *
+  * aa_dfa_null_transition transitions to the next state after a null
+  * character which is not used in standard matching and is only
+  * used to separate pairs.
+  */
+ static inline unsigned int aa_dfa_null_transition(struct aa_dfa *dfa,
+                                                 unsigned int start)
+ {
+       /* the null transition only needs the string's null terminator byte */
+       return aa_dfa_next(dfa, start, 0);
+ }
+ static inline bool path_mediated_fs(struct dentry *dentry)
+ {
+       return !(dentry->d_sb->s_flags & MS_NOUSER);
+ }
+ /* struct aa_policy - common part of both namespaces and profiles
+  * @name: name of the object
+  * @hname - The hierarchical name
+  * @list: list policy object is on
+  * @profiles: head of the profiles list contained in the object
+  */
+ struct aa_policy {
+       const char *name;
+       const char *hname;
+       struct list_head list;
+       struct list_head profiles;
+ };
+ /**
+  * basename - find the last component of an hname
+  * @name: hname to find the base profile name component of  (NOT NULL)
+  *
+  * Returns: the tail (base profile name) name component of an hname
+  */
+ static inline const char *basename(const char *hname)
+ {
+       char *split;
+       hname = strim((char *)hname);
+       for (split = strstr(hname, "//"); split; split = strstr(hname, "//"))
+               hname = split + 2;
+       return hname;
+ }
+ /**
+  * __policy_find - find a policy by @name on a policy list
+  * @head: list to search  (NOT NULL)
+  * @name: name to search for  (NOT NULL)
+  *
+  * Requires: rcu_read_lock be held
+  *
+  * Returns: unrefcounted policy that match @name or NULL if not found
+  */
+ static inline struct aa_policy *__policy_find(struct list_head *head,
+                                             const char *name)
+ {
+       struct aa_policy *policy;
+       list_for_each_entry_rcu(policy, head, list) {
+               if (!strcmp(policy->name, name))
+                       return policy;
+       }
+       return NULL;
+ }
+ /**
+  * __policy_strn_find - find a policy that's name matches @len chars of @str
+  * @head: list to search  (NOT NULL)
+  * @str: string to search for  (NOT NULL)
+  * @len: length of match required
+  *
+  * Requires: rcu_read_lock be held
+  *
+  * Returns: unrefcounted policy that match @str or NULL if not found
+  *
+  * if @len == strlen(@strlen) then this is equiv to __policy_find
+  * other wise it allows searching for policy by a partial match of name
+  */
+ static inline struct aa_policy *__policy_strn_find(struct list_head *head,
+                                           const char *str, int len)
+ {
+       struct aa_policy *policy;
+       list_for_each_entry_rcu(policy, head, list) {
+               if (aa_strneq(policy->name, str, len))
+                       return policy;
+       }
+       return NULL;
+ }
+ bool aa_policy_init(struct aa_policy *policy, const char *prefix,
+                   const char *name, gfp_t gfp);
+ void aa_policy_destroy(struct aa_policy *policy);
+ #endif /* AA_LIB_H */
index 46467aaa557b4b0c8d80b11e07d845d867009ba4,93b1b1f440d339d4271540a5af2c4e988bcbe9bc..67bc96afe54185dff2b0792d5a4cfde8917fdb74
@@@ -18,6 -18,7 +18,7 @@@
  #include <linux/capability.h>
  #include <linux/cred.h>
  #include <linux/kref.h>
+ #include <linux/rhashtable.h>
  #include <linux/sched.h>
  #include <linux/slab.h>
  #include <linux/socket.h>
  #include "capability.h"
  #include "domain.h"
  #include "file.h"
+ #include "lib.h"
  #include "resource.h"
  
+ struct aa_ns;
+ extern int unprivileged_userns_apparmor_policy;
  extern const char *const aa_profile_mode_names[];
  #define APPARMOR_MODE_NAMES_MAX_INDEX 4
  
@@@ -42,7 -49,7 +49,7 @@@
  
  #define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT)
  
- #define PROFILE_INVALID(_profile) ((_profile)->flags & PFLAG_INVALID)
+ #define profile_is_stale(_profile) ((_profile)->flags & PFLAG_STALE)
  
  #define on_list_rcu(X) (!list_empty(X) && (X)->prev != LIST_POISON2)
  
@@@ -67,7 -74,7 +74,7 @@@ enum profile_flags 
        PFLAG_USER_DEFINED = 0x20,      /* user based profile - lower privs */
        PFLAG_NO_LIST_REF = 0x40,       /* list doesn't keep profile ref */
        PFLAG_OLD_NULL_TRANS = 0x100,   /* use // as the null transition */
-       PFLAG_INVALID = 0x200,          /* profile replaced/removed */
+       PFLAG_STALE = 0x200,            /* profile replaced/removed */
        PFLAG_NS_COUNT = 0x400,         /* carries NS ref count */
  
        /* These flags must correspond with PATH_flags */
  
  struct aa_profile;
  
- /* struct aa_policy - common part of both namespaces and profiles
-  * @name: name of the object
-  * @hname - The hierarchical name
-  * @list: list policy object is on
-  * @profiles: head of the profiles list contained in the object
-  */
- struct aa_policy {
-       char *name;
-       char *hname;
-       struct list_head list;
-       struct list_head profiles;
- };
- /* struct aa_ns_acct - accounting of profiles in namespace
-  * @max_size: maximum space allowed for all profiles in namespace
-  * @max_count: maximum number of profiles that can be in this namespace
-  * @size: current size of profiles
-  * @count: current count of profiles (includes null profiles)
-  */
- struct aa_ns_acct {
-       int max_size;
-       int max_count;
-       int size;
-       int count;
- };
- /* struct aa_namespace - namespace for a set of profiles
-  * @base: common policy
-  * @parent: parent of namespace
-  * @lock: lock for modifying the object
-  * @acct: accounting for the namespace
-  * @unconfined: special unconfined profile for the namespace
-  * @sub_ns: list of namespaces under the current namespace.
-  * @uniq_null: uniq value used for null learning profiles
-  * @uniq_id: a unique id count for the profiles in the namespace
-  * @dents: dentries for the namespaces file entries in apparmorfs
-  *
-  * An aa_namespace defines the set profiles that are searched to determine
-  * which profile to attach to a task.  Profiles can not be shared between
-  * aa_namespaces and profile names within a namespace are guaranteed to be
-  * unique.  When profiles in separate namespaces have the same name they
-  * are NOT considered to be equivalent.
-  *
-  * Namespaces are hierarchical and only namespaces and profiles below the
-  * current namespace are visible.
-  *
-  * Namespace names must be unique and can not contain the characters :/\0
-  *
-  * FIXME TODO: add vserver support of namespaces (can it all be done in
-  *             userspace?)
-  */
- struct aa_namespace {
-       struct aa_policy base;
-       struct aa_namespace *parent;
-       struct mutex lock;
-       struct aa_ns_acct acct;
-       struct aa_profile *unconfined;
-       struct list_head sub_ns;
-       atomic_t uniq_null;
-       long uniq_id;
-       struct dentry *dents[AAFS_NS_SIZEOF];
- };
  /* struct aa_policydb - match engine for a policy
   * dfa: dfa pattern match
   * start: set of start states for the different classes of data
@@@ -151,11 -94,24 +94,24 @@@ struct aa_policydb 
  
  };
  
- struct aa_replacedby {
+ struct aa_proxy {
        struct kref count;
        struct aa_profile __rcu *profile;
  };
  
+ /* struct aa_data - generic data structure
+  * key: name for retrieving this data
+  * size: size of data in bytes
+  * data: binary data
+  * head: reserved for rhashtable
+  */
+ struct aa_data {
+       char *key;
+       u32 size;
+       char *data;
+       struct rhash_head head;
+ };
  
  /* struct aa_profile - basic confinement data
   * @base - base components of the profile (name, refcount, lists, lock ...)
   * @rcu: rcu head used when removing from @list
   * @parent: parent of profile
   * @ns: namespace the profile is in
-  * @replacedby: is set to the profile that replaced this profile
+  * @proxy: is set to the profile that replaced this profile
   * @rename: optional profile name that this profile renamed
   * @attach: human readable attachment string
   * @xmatch: optional extended matching for unconfined executables names
   *
   * @dents: dentries for the profiles file entries in apparmorfs
   * @dirname: name of the profile dir in apparmorfs
+  * @data: hashtable for free-form policy aa_data
   *
   * The AppArmor profile contains the basic confinement data.  Each profile
   * has a name, and exists in a namespace.  The @name and @exec_match are
   * used to determine profile attachment against unconfined tasks.  All other
   * attachments are determined by profile X transition rules.
   *
-  * The @replacedby struct is write protected by the profile lock.
+  * The @proxy struct is write protected by the profile lock.
   *
   * Profiles have a hierarchy where hats and children profiles keep
   * a reference to their parent.
@@@ -201,8 -158,8 +158,8 @@@ struct aa_profile 
        struct rcu_head rcu;
        struct aa_profile __rcu *parent;
  
-       struct aa_namespace *ns;
-       struct aa_replacedby *replacedby;
+       struct aa_ns *ns;
+       struct aa_proxy *proxy;
        const char *rename;
  
        const char *attach;
        struct aa_caps caps;
        struct aa_rlimit rlimits;
  
+       struct aa_loaddata *rawdata;
        unsigned char *hash;
        char *dirname;
        struct dentry *dents[AAFS_PROF_SIZEOF];
+       struct rhashtable *data;
  };
  
- extern struct aa_namespace *root_ns;
  extern enum profile_mode aa_g_profile_mode;
  
- void aa_add_profile(struct aa_policy *common, struct aa_profile *profile);
- bool aa_ns_visible(struct aa_namespace *curr, struct aa_namespace *view);
- const char *aa_ns_name(struct aa_namespace *parent, struct aa_namespace *child);
- int aa_alloc_root_ns(void);
- void aa_free_root_ns(void);
- void aa_free_namespace_kref(struct kref *kref);
+ void __aa_update_proxy(struct aa_profile *orig, struct aa_profile *new);
  
- struct aa_namespace *aa_find_namespace(struct aa_namespace *root,
-                                      const char *name);
+ void aa_add_profile(struct aa_policy *common, struct aa_profile *profile);
  
  
- void aa_free_replacedby_kref(struct kref *kref);
- struct aa_profile *aa_alloc_profile(const char *name);
- struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat);
+ void aa_free_proxy_kref(struct kref *kref);
+ struct aa_profile *aa_alloc_profile(const char *name, gfp_t gfp);
+ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
+                                      const char *base, gfp_t gfp);
  void aa_free_profile(struct aa_profile *profile);
  void aa_free_profile_kref(struct kref *kref);
  struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name);
- struct aa_profile *aa_lookup_profile(struct aa_namespace *ns, const char *name);
- struct aa_profile *aa_match_profile(struct aa_namespace *ns, const char *name);
- ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace);
- ssize_t aa_remove_profiles(char *name, size_t size);
+ struct aa_profile *aa_lookupn_profile(struct aa_ns *ns, const char *hname,
+                                     size_t n);
+ struct aa_profile *aa_lookup_profile(struct aa_ns *ns, const char *name);
+ struct aa_profile *aa_fqlookupn_profile(struct aa_profile *base,
+                                       const char *fqname, size_t n);
+ struct aa_profile *aa_match_profile(struct aa_ns *ns, const char *name);
+ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
+                           bool noreplace, struct aa_loaddata *udata);
+ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *profile,
+                           char *name, size_t size);
+ void __aa_profile_list_release(struct list_head *head);
  
  #define PROF_ADD 1
  #define PROF_REPLACE 0
  #define unconfined(X) ((X)->mode == APPARMOR_UNCONFINED)
  
  
- static inline struct aa_profile *aa_deref_parent(struct aa_profile *p)
- {
-       return rcu_dereference_protected(p->parent,
-                                        mutex_is_locked(&p->ns->lock));
- }
  /**
   * aa_get_profile - increment refcount on profile @p
   * @p: profile  (MAYBE NULL)
@@@ -287,7 -240,7 +240,7 @@@ static inline struct aa_profile *aa_get
   */
  static inline struct aa_profile *aa_get_profile_not0(struct aa_profile *p)
  {
 -      if (p && kref_get_not0(&p->count))
 +      if (p && kref_get_unless_zero(&p->count))
                return p;
  
        return NULL;
@@@ -307,7 -260,7 +260,7 @@@ static inline struct aa_profile *aa_get
        rcu_read_lock();
        do {
                c = rcu_dereference(*p);
 -      } while (c && !kref_get_not0(&c->count));
 +      } while (c && !kref_get_unless_zero(&c->count));
        rcu_read_unlock();
  
        return c;
@@@ -326,8 -279,8 +279,8 @@@ static inline struct aa_profile *aa_get
        if (!p)
                return NULL;
  
-       if (PROFILE_INVALID(p))
-               return aa_get_profile_rcu(&p->replacedby->profile);
+       if (profile_is_stale(p))
+               return aa_get_profile_rcu(&p->proxy->profile);
  
        return aa_get_profile(p);
  }
@@@ -342,7 -295,7 +295,7 @@@ static inline void aa_put_profile(struc
                kref_put(&p->count, aa_free_profile_kref);
  }
  
- static inline struct aa_replacedby *aa_get_replacedby(struct aa_replacedby *p)
+ static inline struct aa_proxy *aa_get_proxy(struct aa_proxy *p)
  {
        if (p)
                kref_get(&(p->count));
        return p;
  }
  
- static inline void aa_put_replacedby(struct aa_replacedby *p)
+ static inline void aa_put_proxy(struct aa_proxy *p)
  {
        if (p)
-               kref_put(&p->count, aa_free_replacedby_kref);
- }
- /* requires profile list write lock held */
- static inline void __aa_update_replacedby(struct aa_profile *orig,
-                                         struct aa_profile *new)
- {
-       struct aa_profile *tmp;
-       tmp = rcu_dereference_protected(orig->replacedby->profile,
-                                       mutex_is_locked(&orig->ns->lock));
-       rcu_assign_pointer(orig->replacedby->profile, aa_get_profile(new));
-       orig->flags |= PFLAG_INVALID;
-       aa_put_profile(tmp);
- }
- /**
-  * aa_get_namespace - increment references count on @ns
-  * @ns: namespace to increment reference count of (MAYBE NULL)
-  *
-  * Returns: pointer to @ns, if @ns is NULL returns NULL
-  * Requires: @ns must be held with valid refcount when called
-  */
- static inline struct aa_namespace *aa_get_namespace(struct aa_namespace *ns)
- {
-       if (ns)
-               aa_get_profile(ns->unconfined);
-       return ns;
- }
- /**
-  * aa_put_namespace - decrement refcount on @ns
-  * @ns: namespace to put reference of
-  *
-  * Decrement reference count of @ns and if no longer in use free it
-  */
- static inline void aa_put_namespace(struct aa_namespace *ns)
- {
-       if (ns)
-               aa_put_profile(ns->unconfined);
+               kref_put(&p->count, aa_free_proxy_kref);
  }
  
  static inline int AUDIT_MODE(struct aa_profile *profile)
        return profile->audit;
  }
  
- bool policy_view_capable(void);
- bool policy_admin_capable(void);
- bool aa_may_manage_policy(int op);
+ bool policy_view_capable(struct aa_ns *ns);
+ bool policy_admin_capable(struct aa_ns *ns);
+ int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns,
+                        const char *op);
  
  #endif /* __AA_POLICY_H */
This page took 0.12678 seconds and 4 git commands to generate.