tunnels: fix netns vs proto registration ordering
[safe/jmp/linux-2.6] / kernel / auditsc.c
index 140c474..fc0f928 100644 (file)
@@ -66,6 +66,7 @@
 #include <linux/syscalls.h>
 #include <linux/inotify.h>
 #include <linux/capability.h>
+#include <linux/fs_struct.h>
 
 #include "audit.h"
 
@@ -124,13 +125,6 @@ struct audit_aux_data {
 /* Number of target pids per aux struct. */
 #define AUDIT_AUX_PIDS 16
 
-struct audit_aux_data_mq_open {
-       struct audit_aux_data   d;
-       int                     oflag;
-       mode_t                  mode;
-       struct mq_attr          attr;
-};
-
 struct audit_aux_data_execve {
        struct audit_aux_data   d;
        int argc;
@@ -138,11 +132,6 @@ struct audit_aux_data_execve {
        struct mm_struct *mm;
 };
 
-struct audit_aux_data_fd_pair {
-       struct  audit_aux_data d;
-       int     fd[2];
-};
-
 struct audit_aux_data_pids {
        struct audit_aux_data   d;
        pid_t                   target_pid[AUDIT_AUX_PIDS];
@@ -177,14 +166,14 @@ struct audit_tree_refs {
 struct audit_context {
        int                 dummy;      /* must be the first element */
        int                 in_syscall; /* 1 if task is in a syscall */
-       enum audit_state    state;
+       enum audit_state    state, current_state;
        unsigned int        serial;     /* serial number for record */
-       struct timespec     ctime;      /* time of syscall entry */
        int                 major;      /* syscall number */
+       struct timespec     ctime;      /* time of syscall entry */
        unsigned long       argv[4];    /* syscall arguments */
-       int                 return_valid; /* return code is valid */
        long                return_code;/* syscall return code */
-       int                 auditable;  /* 1 if record should be written */
+       u64                 prio;
+       int                 return_valid; /* return code is valid */
        int                 name_count;
        struct audit_names  names[AUDIT_NAMES];
        char *              filterkey;  /* key for rule that triggered record */
@@ -209,6 +198,7 @@ struct audit_context {
        char                target_comm[TASK_COMM_LEN];
 
        struct audit_tree_refs *trees, *first_trees;
+       struct list_head killed_trees;
        int tree_count;
 
        int type;
@@ -242,7 +232,17 @@ struct audit_context {
                        unsigned int            msg_prio;
                        struct timespec         abs_timeout;
                } mq_sendrecv;
+               struct {
+                       int                     oflag;
+                       mode_t                  mode;
+                       struct mq_attr          attr;
+               } mq_open;
+               struct {
+                       pid_t                   pid;
+                       struct audit_cap_data   cap;
+               } capset;
        };
+       int fds[2];
 
 #if AUDIT_DEBUG
        int                 put_count;
@@ -250,7 +250,6 @@ struct audit_context {
 #endif
 };
 
-#define ACC_MODE(x) ("\004\002\006\006"[(x)&O_ACCMODE])
 static inline int open_arg(int flags, int mask)
 {
        int n = ACC_MODE(flags);
@@ -330,6 +329,14 @@ static int audit_match_filetype(struct audit_context *ctx, int which)
  */
 
 #ifdef CONFIG_AUDIT_TREE
+static void audit_set_auditable(struct audit_context *ctx)
+{
+       if (!ctx->prio) {
+               ctx->prio = 1;
+               ctx->current_state = AUDIT_RECORD_CONTEXT;
+       }
+}
+
 static int put_tree_ref(struct audit_context *ctx, struct audit_chunk *chunk)
 {
        struct audit_tree_refs *p = ctx->trees;
@@ -541,9 +548,9 @@ static int audit_filter_rules(struct task_struct *tsk,
                        }
                        break;
                case AUDIT_WATCH:
-                       if (name && rule->watch->ino != (unsigned long)-1)
-                               result = (name->dev == rule->watch->dev &&
-                                         name->ino == rule->watch->ino);
+                       if (name && audit_watch_inode(rule->watch) != (unsigned long)-1)
+                               result = (name->dev == audit_watch_dev(rule->watch) &&
+                                         name->ino == audit_watch_inode(rule->watch));
                        break;
                case AUDIT_DIR:
                        if (ctx)
@@ -632,8 +639,16 @@ static int audit_filter_rules(struct task_struct *tsk,
                        return 0;
                }
        }
-       if (rule->filterkey && ctx)
-               ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC);
+
+       if (ctx) {
+               if (rule->prio <= ctx->prio)
+                       return 0;
+               if (rule->filterkey) {
+                       kfree(ctx->filterkey);
+                       ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC);
+               }
+               ctx->prio = rule->prio;
+       }
        switch (rule->action) {
        case AUDIT_NEVER:    *state = AUDIT_DISABLED;       break;
        case AUDIT_ALWAYS:   *state = AUDIT_RECORD_CONTEXT; break;
@@ -646,7 +661,7 @@ static int audit_filter_rules(struct task_struct *tsk,
  * completely disabled for this task.  Since we only have the task
  * structure at this point, we can only check uid and gid.
  */
-static enum audit_state audit_filter_task(struct task_struct *tsk)
+static enum audit_state audit_filter_task(struct task_struct *tsk, char **key)
 {
        struct audit_entry *e;
        enum audit_state   state;
@@ -654,6 +669,8 @@ static enum audit_state audit_filter_task(struct task_struct *tsk)
        rcu_read_lock();
        list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) {
                if (audit_filter_rules(tsk, &e->rule, NULL, NULL, &state)) {
+                       if (state == AUDIT_RECORD_CONTEXT)
+                               *key = kstrdup(e->rule.filterkey, GFP_ATOMIC);
                        rcu_read_unlock();
                        return state;
                }
@@ -687,6 +704,7 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk,
                            audit_filter_rules(tsk, &e->rule, ctx, NULL,
                                               &state)) {
                                rcu_read_unlock();
+                               ctx->current_state = state;
                                return state;
                        }
                }
@@ -700,15 +718,14 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk,
  * buckets applicable to the inode numbers in audit_names[].
  * Regarding audit_state, same rules apply as for audit_filter_syscall().
  */
-enum audit_state audit_filter_inodes(struct task_struct *tsk,
-                                    struct audit_context *ctx)
+void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx)
 {
        int i;
        struct audit_entry *e;
        enum audit_state state;
 
        if (audit_pid && tsk->tgid == audit_pid)
-               return AUDIT_DISABLED;
+               return;
 
        rcu_read_lock();
        for (i = 0; i < ctx->name_count; i++) {
@@ -725,22 +742,17 @@ enum audit_state audit_filter_inodes(struct task_struct *tsk,
                        if ((e->rule.mask[word] & bit) == bit &&
                            audit_filter_rules(tsk, &e->rule, ctx, n, &state)) {
                                rcu_read_unlock();
-                               return state;
+                               ctx->current_state = state;
+                               return;
                        }
                }
        }
        rcu_read_unlock();
-       return AUDIT_BUILD_CONTEXT;
-}
-
-void audit_set_auditable(struct audit_context *ctx)
-{
-       ctx->auditable = 1;
 }
 
 static inline struct audit_context *audit_get_context(struct task_struct *tsk,
                                                      int return_valid,
-                                                     int return_code)
+                                                     long return_code)
 {
        struct audit_context *context = tsk->audit_context;
 
@@ -766,23 +778,11 @@ static inline struct audit_context *audit_get_context(struct task_struct *tsk,
        else
                context->return_code  = return_code;
 
-       if (context->in_syscall && !context->dummy && !context->auditable) {
-               enum audit_state state;
-
-               state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]);
-               if (state == AUDIT_RECORD_CONTEXT) {
-                       context->auditable = 1;
-                       goto get_context;
-               }
-
-               state = audit_filter_inodes(tsk, context);
-               if (state == AUDIT_RECORD_CONTEXT)
-                       context->auditable = 1;
-
+       if (context->in_syscall && !context->dummy) {
+               audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]);
+               audit_filter_inodes(tsk, context);
        }
 
-get_context:
-
        tsk->audit_context = NULL;
        return context;
 }
@@ -792,8 +792,7 @@ static inline void audit_free_names(struct audit_context *context)
        int i;
 
 #if AUDIT_DEBUG == 2
-       if (context->auditable
-           ||context->put_count + context->ino_count != context->name_count) {
+       if (context->put_count + context->ino_count != context->name_count) {
                printk(KERN_ERR "%s:%d(:%d): major=%d in_syscall=%d"
                       " name_count=%d put_count=%d"
                       " ino_count=%d [NOT freeing]\n",
@@ -844,6 +843,7 @@ static inline void audit_zero_context(struct audit_context *context,
 {
        memset(context, 0, sizeof(*context));
        context->state      = state;
+       context->prio = state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0;
 }
 
 static inline struct audit_context *audit_alloc_context(enum audit_state state)
@@ -853,6 +853,7 @@ static inline struct audit_context *audit_alloc_context(enum audit_state state)
        if (!(context = kmalloc(sizeof(*context), GFP_KERNEL)))
                return NULL;
        audit_zero_context(context, state);
+       INIT_LIST_HEAD(&context->killed_trees);
        return context;
 }
 
@@ -869,18 +870,21 @@ int audit_alloc(struct task_struct *tsk)
 {
        struct audit_context *context;
        enum audit_state     state;
+       char *key = NULL;
 
        if (likely(!audit_ever_enabled))
                return 0; /* Return if not auditing. */
 
-       state = audit_filter_task(tsk);
+       state = audit_filter_task(tsk, &key);
        if (likely(state == AUDIT_DISABLED))
                return 0;
 
        if (!(context = audit_alloc_context(state))) {
+               kfree(key);
                audit_log_lost("out of memory in audit_alloc");
                return -ENOMEM;
        }
+       context->filterkey = key;
 
        tsk->audit_context  = context;
        set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
@@ -1021,8 +1025,8 @@ static int audit_log_single_execve_arg(struct audit_context *context,
 {
        char arg_num_len_buf[12];
        const char __user *tmp_p = p;
-       /* how many digits are in arg_num? 3 is the length of a=\n */
-       size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) + 3;
+       /* how many digits are in arg_num? 5 is the length of ' a=""' */
+       size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) + 5;
        size_t len, len_left, to_send;
        size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN;
        unsigned int i, has_cntl = 0, too_long = 0;
@@ -1107,7 +1111,7 @@ static int audit_log_single_execve_arg(struct audit_context *context,
                 * so we can be sure nothing was lost.
                 */
                if ((i == 0) && (too_long))
-                       audit_log_format(*ab, "a%d_len=%zu ", arg_num,
+                       audit_log_format(*ab, " a%d_len=%zu", arg_num,
                                         has_cntl ? 2*len : len);
 
                /*
@@ -1127,15 +1131,14 @@ static int audit_log_single_execve_arg(struct audit_context *context,
                buf[to_send] = '\0';
 
                /* actually log it */
-               audit_log_format(*ab, "a%d", arg_num);
+               audit_log_format(*ab, " a%d", arg_num);
                if (too_long)
                        audit_log_format(*ab, "[%d]", i);
                audit_log_format(*ab, "=");
                if (has_cntl)
                        audit_log_n_hex(*ab, buf, to_send);
                else
-                       audit_log_format(*ab, "\"%s\"", buf);
-               audit_log_format(*ab, "\n");
+                       audit_log_string(*ab, buf);
 
                p += to_send;
                len_left -= to_send;
@@ -1163,7 +1166,7 @@ static void audit_log_execve_info(struct audit_context *context,
 
        p = (const char __user *)axi->mm->arg_start;
 
-       audit_log_format(*ab, "argc=%d ", axi->argc);
+       audit_log_format(*ab, "argc=%d", axi->argc);
 
        /*
         * we need some kernel buffer to hold the userspace args.  Just
@@ -1263,6 +1266,16 @@ static void show_special(struct audit_context *context, int *call_panic)
                                return;
                }
                break; }
+       case AUDIT_MQ_OPEN: {
+               audit_log_format(ab,
+                       "oflag=0x%x mode=%#o mq_flags=0x%lx mq_maxmsg=%ld "
+                       "mq_msgsize=%ld mq_curmsgs=%ld",
+                       context->mq_open.oflag, context->mq_open.mode,
+                       context->mq_open.attr.mq_flags,
+                       context->mq_open.attr.mq_maxmsg,
+                       context->mq_open.attr.mq_msgsize,
+                       context->mq_open.attr.mq_curmsgs);
+               break; }
        case AUDIT_MQ_SENDRECV: {
                audit_log_format(ab,
                        "mqdes=%d msg_len=%zd msg_prio=%u "
@@ -1287,6 +1300,12 @@ static void show_special(struct audit_context *context, int *call_panic)
                        attr->mq_flags, attr->mq_maxmsg,
                        attr->mq_msgsize, attr->mq_curmsgs);
                break; }
+       case AUDIT_CAPSET: {
+               audit_log_format(ab, "pid=%d", context->capset.pid);
+               audit_log_cap(ab, "cap_pi", &context->capset.cap.inheritable);
+               audit_log_cap(ab, "cap_pp", &context->capset.cap.permitted);
+               audit_log_cap(ab, "cap_pe", &context->capset.cap.effective);
+               break; }
        }
        audit_log_end(ab);
 }
@@ -1354,11 +1373,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
 
 
        audit_log_task_info(ab, tsk);
-       if (context->filterkey) {
-               audit_log_format(ab, " key=");
-               audit_log_untrustedstring(ab, context->filterkey);
-       } else
-               audit_log_format(ab, " key=(null)");
+       audit_log_key(ab, context->filterkey);
        audit_log_end(ab);
 
        for (aux = context->aux; aux; aux = aux->next) {
@@ -1368,26 +1383,12 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
                        continue; /* audit_panic has been called */
 
                switch (aux->type) {
-               case AUDIT_MQ_OPEN: {
-                       struct audit_aux_data_mq_open *axi = (void *)aux;
-                       audit_log_format(ab,
-                               "oflag=0x%x mode=%#o mq_flags=0x%lx mq_maxmsg=%ld "
-                               "mq_msgsize=%ld mq_curmsgs=%ld",
-                               axi->oflag, axi->mode, axi->attr.mq_flags,
-                               axi->attr.mq_maxmsg, axi->attr.mq_msgsize,
-                               axi->attr.mq_curmsgs);
-                       break; }
 
                case AUDIT_EXECVE: {
                        struct audit_aux_data_execve *axi = (void *)aux;
                        audit_log_execve_info(context, &ab, axi);
                        break; }
 
-               case AUDIT_FD_PAIR: {
-                       struct audit_aux_data_fd_pair *axs = (void *)aux;
-                       audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]);
-                       break; }
-
                case AUDIT_BPRM_FCAPS: {
                        struct audit_aux_data_bprm_fcaps *axs = (void *)aux;
                        audit_log_format(ab, "fver=%x", axs->fcap_ver);
@@ -1402,14 +1403,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
                        audit_log_cap(ab, "new_pe", &axs->new_pcap.effective);
                        break; }
 
-               case AUDIT_CAPSET: {
-                       struct audit_aux_data_capset *axs = (void *)aux;
-                       audit_log_format(ab, "pid=%d", axs->pid);
-                       audit_log_cap(ab, "cap_pi", &axs->cap.inheritable);
-                       audit_log_cap(ab, "cap_pp", &axs->cap.permitted);
-                       audit_log_cap(ab, "cap_pe", &axs->cap.effective);
-                       break; }
-
                }
                audit_log_end(ab);
        }
@@ -1417,6 +1410,15 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
        if (context->type)
                show_special(context, &call_panic);
 
+       if (context->fds[0] >= 0) {
+               ab = audit_log_start(context, GFP_KERNEL, AUDIT_FD_PAIR);
+               if (ab) {
+                       audit_log_format(ab, "fd0=%d fd1=%d",
+                                       context->fds[0], context->fds[1]);
+                       audit_log_end(ab);
+               }
+       }
+
        if (context->sockaddr_len) {
                ab = audit_log_start(context, GFP_KERNEL, AUDIT_SOCKADDR);
                if (ab) {
@@ -1473,7 +1475,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
                        case 0:
                                /* name was specified as a relative path and the
                                 * directory component is the cwd */
-                               audit_log_d_path(ab, " name=", &context->pwd);
+                               audit_log_d_path(ab, "name=", &context->pwd);
                                break;
                        default:
                                /* log the name's directory component */
@@ -1542,8 +1544,10 @@ void audit_free(struct task_struct *tsk)
         * We use GFP_ATOMIC here because we might be doing this
         * in the context of the idle thread */
        /* that can happen only if we are called from do_exit() */
-       if (context->in_syscall && context->auditable)
+       if (context->in_syscall && context->current_state == AUDIT_RECORD_CONTEXT)
                audit_log_exit(context, tsk);
+       if (!list_empty(&context->killed_trees))
+               audit_kill_trees(&context->killed_trees);
 
        audit_free_context(context);
 }
@@ -1626,15 +1630,17 @@ void audit_syscall_entry(int arch, int major,
 
        state = context->state;
        context->dummy = !audit_n_rules;
-       if (!context->dummy && (state == AUDIT_SETUP_CONTEXT || state == AUDIT_BUILD_CONTEXT))
+       if (!context->dummy && state == AUDIT_BUILD_CONTEXT) {
+               context->prio = 0;
                state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_ENTRY]);
+       }
        if (likely(state == AUDIT_DISABLED))
                return;
 
        context->serial     = 0;
        context->ctime      = CURRENT_TIME;
        context->in_syscall = 1;
-       context->auditable  = !!(state == AUDIT_RECORD_CONTEXT);
+       context->current_state  = state;
        context->ppid       = 0;
 }
 
@@ -1642,17 +1648,20 @@ void audit_finish_fork(struct task_struct *child)
 {
        struct audit_context *ctx = current->audit_context;
        struct audit_context *p = child->audit_context;
-       if (!p || !ctx || !ctx->auditable)
+       if (!p || !ctx)
+               return;
+       if (!ctx->in_syscall || ctx->current_state != AUDIT_RECORD_CONTEXT)
                return;
        p->arch = ctx->arch;
        p->major = ctx->major;
        memcpy(p->argv, ctx->argv, sizeof(ctx->argv));
        p->ctime = ctx->ctime;
        p->dummy = ctx->dummy;
-       p->auditable = ctx->auditable;
        p->in_syscall = ctx->in_syscall;
        p->filterkey = kstrdup(ctx->filterkey, GFP_KERNEL);
        p->ppid = current->pid;
+       p->prio = ctx->prio;
+       p->current_state = ctx->current_state;
 }
 
 /**
@@ -1676,11 +1685,14 @@ void audit_syscall_exit(int valid, long return_code)
        if (likely(!context))
                return;
 
-       if (context->in_syscall && context->auditable)
+       if (context->in_syscall && context->current_state == AUDIT_RECORD_CONTEXT)
                audit_log_exit(context, tsk);
 
        context->in_syscall = 0;
-       context->auditable  = 0;
+       context->prio = context->state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0;
+
+       if (!list_empty(&context->killed_trees))
+               audit_kill_trees(&context->killed_trees);
 
        if (context->previous) {
                struct audit_context *new_context = context->previous;
@@ -1697,8 +1709,11 @@ void audit_syscall_exit(int valid, long return_code)
                context->target_sid = 0;
                context->sockaddr_len = 0;
                context->type = 0;
-               kfree(context->filterkey);
-               context->filterkey = NULL;
+               context->fds[0] = -1;
+               if (context->state != AUDIT_RECORD_CONTEXT) {
+                       kfree(context->filterkey);
+                       context->filterkey = NULL;
+               }
                tsk->audit_context = context;
        }
 }
@@ -2089,7 +2104,10 @@ int auditsc_get_stamp(struct audit_context *ctx,
        t->tv_sec  = ctx->ctime.tv_sec;
        t->tv_nsec = ctx->ctime.tv_nsec;
        *serial    = ctx->serial;
-       ctx->auditable = 1;
+       if (!ctx->prio) {
+               ctx->prio = 1;
+               ctx->current_state = AUDIT_RECORD_CONTEXT;
+       }
        return 1;
 }
 
@@ -2133,40 +2151,22 @@ int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
  * __audit_mq_open - record audit data for a POSIX MQ open
  * @oflag: open flag
  * @mode: mode bits
- * @u_attr: queue attributes
+ * @attr: queue attributes
  *
- * Returns 0 for success or NULL context or < 0 on error.
  */
-int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr)
+void __audit_mq_open(int oflag, mode_t mode, struct mq_attr *attr)
 {
-       struct audit_aux_data_mq_open *ax;
        struct audit_context *context = current->audit_context;
 
-       if (!audit_enabled)
-               return 0;
-
-       if (likely(!context))
-               return 0;
-
-       ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
-       if (!ax)
-               return -ENOMEM;
-
-       if (u_attr != NULL) {
-               if (copy_from_user(&ax->attr, u_attr, sizeof(ax->attr))) {
-                       kfree(ax);
-                       return -EFAULT;
-               }
-       } else
-               memset(&ax->attr, 0, sizeof(ax->attr));
+       if (attr)
+               memcpy(&context->mq_open.attr, attr, sizeof(struct mq_attr));
+       else
+               memset(&context->mq_open.attr, 0, sizeof(struct mq_attr));
 
-       ax->oflag = oflag;
-       ax->mode = mode;
+       context->mq_open.oflag = oflag;
+       context->mq_open.mode = mode;
 
-       ax->d.type = AUDIT_MQ_OPEN;
-       ax->d.next = context->aux;
-       context->aux = (void *)ax;
-       return 0;
+       context->type = AUDIT_MQ_OPEN;
 }
 
 /**
@@ -2198,7 +2198,7 @@ void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,
 /**
  * __audit_mq_notify - record audit data for a POSIX MQ notify
  * @mqdes: MQ descriptor
- * @u_notification: Notification event
+ * @notification: Notification event
  *
  */
 
@@ -2310,29 +2310,12 @@ void audit_socketcall(int nargs, unsigned long *args)
  * @fd1: the first file descriptor
  * @fd2: the second file descriptor
  *
- * Returns 0 for success or NULL context or < 0 on error.
  */
-int __audit_fd_pair(int fd1, int fd2)
+void __audit_fd_pair(int fd1, int fd2)
 {
        struct audit_context *context = current->audit_context;
-       struct audit_aux_data_fd_pair *ax;
-
-       if (likely(!context)) {
-               return 0;
-       }
-
-       ax = kmalloc(sizeof(*ax), GFP_KERNEL);
-       if (!ax) {
-               return -ENOMEM;
-       }
-
-       ax->fd[0] = fd1;
-       ax->fd[1] = fd2;
-
-       ax->d.type = AUDIT_FD_PAIR;
-       ax->d.next = context->aux;
-       context->aux = (void *)ax;
-       return 0;
+       context->fds[0] = fd1;
+       context->fds[1] = fd2;
 }
 
 /**
@@ -2491,29 +2474,15 @@ int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
  * Record the aguments userspace sent to sys_capset for later printing by the
  * audit system if applicable
  */
-int __audit_log_capset(pid_t pid,
+void __audit_log_capset(pid_t pid,
                       const struct cred *new, const struct cred *old)
 {
-       struct audit_aux_data_capset *ax;
        struct audit_context *context = current->audit_context;
-
-       if (likely(!audit_enabled || !context || context->dummy))
-               return 0;
-
-       ax = kmalloc(sizeof(*ax), GFP_KERNEL);
-       if (!ax)
-               return -ENOMEM;
-
-       ax->d.type = AUDIT_CAPSET;
-       ax->d.next = context->aux;
-       context->aux = (void *)ax;
-
-       ax->pid = pid;
-       ax->cap.effective   = new->cap_effective;
-       ax->cap.inheritable = new->cap_effective;
-       ax->cap.permitted   = new->cap_permitted;
-
-       return 0;
+       context->capset.pid = pid;
+       context->capset.cap.effective   = new->cap_effective;
+       context->capset.cap.inheritable = new->cap_effective;
+       context->capset.cap.permitted   = new->cap_permitted;
+       context->type = AUDIT_CAPSET;
 }
 
 /**
@@ -2558,3 +2527,11 @@ void audit_core_dumps(long signr)
        audit_log_format(ab, " sig=%ld", signr);
        audit_log_end(ab);
 }
+
+struct list_head *audit_killed_trees(void)
+{
+       struct audit_context *ctx = current->audit_context;
+       if (likely(!ctx || !ctx->in_syscall))
+               return NULL;
+       return &ctx->killed_trees;
+}