]> err.no Git - linux-2.6/blobdiff - kernel/auditsc.c
kexec: use a mutex for locking rather than xchg()
[linux-2.6] / kernel / auditsc.c
index e128adcb33c2313011579236213ee424724df616..972f8e61d36ac4ca7742038b2a3f3004f1857eb9 100644 (file)
@@ -243,6 +243,9 @@ static inline int open_arg(int flags, int mask)
 
 static int audit_match_perm(struct audit_context *ctx, int mask)
 {
+       if (unlikely(!ctx))
+               return 0;
+
        unsigned n = ctx->major;
        switch (audit_classify_syscall(ctx->arch, n)) {
        case 0: /* native */
@@ -280,6 +283,23 @@ static int audit_match_perm(struct audit_context *ctx, int mask)
        }
 }
 
+static int audit_match_filetype(struct audit_context *ctx, int which)
+{
+       unsigned index = which & ~S_IFMT;
+       mode_t mode = which & S_IFMT;
+
+       if (unlikely(!ctx))
+               return 0;
+
+       if (index >= ctx->name_count)
+               return 0;
+       if (ctx->names[index].ino == -1)
+               return 0;
+       if ((ctx->names[index].mode ^ mode) & S_IFMT)
+               return 0;
+       return 1;
+}
+
 /*
  * We keep a linked list of fixed-sized (31 pointer) arrays of audit_chunk *;
  * ->first_trees points to its beginning, ->trees - to the current end of data.
@@ -589,12 +609,15 @@ static int audit_filter_rules(struct task_struct *tsk,
                case AUDIT_PERM:
                        result = audit_match_perm(ctx, f->val);
                        break;
+               case AUDIT_FILETYPE:
+                       result = audit_match_filetype(ctx, f->val);
+                       break;
                }
 
                if (!result)
                        return 0;
        }
-       if (rule->filterkey)
+       if (rule->filterkey && ctx)
                ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC);
        switch (rule->action) {
        case AUDIT_NEVER:    *state = AUDIT_DISABLED;       break;
@@ -1293,7 +1316,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
                        break; }
 
                case AUDIT_SOCKETCALL: {
-                       int i;
                        struct audit_aux_data_socketcall *axs = (void *)aux;
                        audit_log_format(ab, "nargs=%d", axs->nargs);
                        for (i=0; i<axs->nargs; i++)
@@ -1318,7 +1340,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
 
        for (aux = context->aux_pids; aux; aux = aux->next) {
                struct audit_aux_data_pids *axs = (void *)aux;
-               int i;
 
                for (i = 0; i < axs->pid_count; i++)
                        if (audit_log_pid_context(context, axs->target_pid[i],
@@ -1462,7 +1483,8 @@ void audit_syscall_entry(int arch, int major,
        struct audit_context *context = tsk->audit_context;
        enum audit_state     state;
 
-       BUG_ON(!context);
+       if (unlikely(!context))
+               return;
 
        /*
         * This happens only on certain architectures that make system
@@ -2360,7 +2382,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
        struct audit_context *ctx = tsk->audit_context;
 
        if (audit_pid && t->tgid == audit_pid) {
-               if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) {
+               if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) {
                        audit_sig_pid = tsk->pid;
                        if (tsk->loginuid != -1)
                                audit_sig_uid = tsk->loginuid;