sanitize audit_ipc_obj()
Al Viro [Wed, 10 Dec 2008 08:40:06 +0000 (03:40 -0500)]
* get rid of allocations
* make it return void
* simplify callers

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

include/linux/audit.h
ipc/shm.c
ipc/util.c
kernel/auditsc.c

index 466a953..f8578b9 100644 (file)
@@ -443,7 +443,7 @@ extern int  audit_set_loginuid(struct task_struct *task, uid_t loginuid);
 #define audit_get_loginuid(t) ((t)->loginuid)
 #define audit_get_sessionid(t) ((t)->sessionid)
 extern void audit_log_task_context(struct audit_buffer *ab);
-extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp);
+extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp);
 extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
 extern int audit_bprm(struct linux_binprm *bprm);
 extern void audit_socketcall(int nargs, unsigned long *args);
@@ -460,11 +460,10 @@ extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
                                  const struct cred *old);
 extern int __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old);
 
-static inline int audit_ipc_obj(struct kern_ipc_perm *ipcp)
+static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
 {
        if (unlikely(!audit_dummy_context()))
-               return __audit_ipc_obj(ipcp);
-       return 0;
+               __audit_ipc_obj(ipcp);
 }
 static inline int audit_fd_pair(int fd1, int fd2)
 {
@@ -546,7 +545,7 @@ extern int audit_signals;
 #define audit_get_loginuid(t) (-1)
 #define audit_get_sessionid(t) (-1)
 #define audit_log_task_context(b) do { ; } while (0)
-#define audit_ipc_obj(i) ({ 0; })
+#define audit_ipc_obj(i) ((void)0)
 #define audit_ipc_set_perm(q,u,g,m) ({ 0; })
 #define audit_bprm(p) ({ 0; })
 #define audit_socketcall(n,a) ((void)0)
index 38a0557..57dd500 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -747,9 +747,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
                        goto out;
                }
 
-               err = audit_ipc_obj(&(shp->shm_perm));
-               if (err)
-                       goto out_unlock;
+               audit_ipc_obj(&(shp->shm_perm));
 
                if (!capable(CAP_IPC_LOCK)) {
                        uid_t euid = current_euid();
index 5a1808c..579552a 100644 (file)
@@ -624,10 +624,9 @@ void ipc_rcu_putref(void *ptr)
 int ipcperms (struct kern_ipc_perm *ipcp, short flag)
 {      /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
        uid_t euid = current_euid();
-       int requested_mode, granted_mode, err;
+       int requested_mode, granted_mode;
 
-       if (unlikely((err = audit_ipc_obj(ipcp))))
-               return err;
+       audit_ipc_obj(ipcp);
        requested_mode = (flag >> 6) | (flag >> 3) | flag;
        granted_mode = ipcp->mode;
        if (euid == ipcp->cuid ||
@@ -803,9 +802,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd,
                goto out_up;
        }
 
-       err = audit_ipc_obj(ipcp);
-       if (err)
-               goto out_unlock;
+       audit_ipc_obj(ipcp);
 
        if (cmd == IPC_SET) {
                err = audit_ipc_set_perm(extra_perm, perm->uid,
index 5cda664..7350431 100644 (file)
@@ -247,6 +247,12 @@ struct audit_context {
                        int nargs;
                        long args[6];
                } socketcall;
+               struct {
+                       uid_t                   uid;
+                       gid_t                   gid;
+                       mode_t                  mode;
+                       u32                     osid;
+               } ipc;
        };
 
 #if AUDIT_DEBUG
@@ -605,19 +611,12 @@ static int audit_filter_rules(struct task_struct *tsk,
                                        }
                                }
                                /* Find ipc objects that match */
-                               if (ctx) {
-                                       struct audit_aux_data *aux;
-                                       for (aux = ctx->aux; aux;
-                                            aux = aux->next) {
-                                               if (aux->type == AUDIT_IPC) {
-                                                       struct audit_aux_data_ipcctl *axi = (void *)aux;
-                                                       if (security_audit_rule_match(axi->osid, f->type, f->op, f->lsm_rule, ctx)) {
-                                                               ++result;
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                               }
+                               if (!ctx || ctx->type != AUDIT_IPC)
+                                       break;
+                               if (security_audit_rule_match(ctx->ipc.osid,
+                                                             f->type, f->op,
+                                                             f->lsm_rule, ctx))
+                                       ++result;
                        }
                        break;
                case AUDIT_ARG0:
@@ -1228,7 +1227,7 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
                audit_log_format(ab, " cap_fe=%d cap_fver=%x", name->fcap.fE, name->fcap_ver);
 }
 
-static void show_special(struct audit_context *context)
+static void show_special(struct audit_context *context, int *call_panic)
 {
        struct audit_buffer *ab;
        int i;
@@ -1245,6 +1244,23 @@ static void show_special(struct audit_context *context)
                        audit_log_format(ab, " a%d=%lx", i,
                                context->socketcall.args[i]);
                break; }
+       case AUDIT_IPC: {
+               u32 osid = context->ipc.osid;
+
+               audit_log_format(ab, "ouid=%u ogid=%u mode=%#o",
+                        context->ipc.uid, context->ipc.gid, context->ipc.mode);
+               if (osid) {
+                       char *ctx = NULL;
+                       u32 len;
+                       if (security_secid_to_secctx(osid, &ctx, &len)) {
+                               audit_log_format(ab, " osid=%u", osid);
+                               *call_panic = 1;
+                       } else {
+                               audit_log_format(ab, " obj=%s", ctx);
+                               security_release_secctx(ctx, len);
+                       }
+               }
+               break; }
        }
        audit_log_end(ab);
 }
@@ -1363,26 +1379,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
                                axi->mqstat.mq_msgsize, axi->mqstat.mq_curmsgs);
                        break; }
 
-               case AUDIT_IPC: {
-                       struct audit_aux_data_ipcctl *axi = (void *)aux;
-                       audit_log_format(ab, 
-                                "ouid=%u ogid=%u mode=%#o",
-                                axi->uid, axi->gid, axi->mode);
-                       if (axi->osid != 0) {
-                               char *ctx = NULL;
-                               u32 len;
-                               if (security_secid_to_secctx(
-                                               axi->osid, &ctx, &len)) {
-                                       audit_log_format(ab, " osid=%u",
-                                                       axi->osid);
-                                       call_panic = 1;
-                               } else {
-                                       audit_log_format(ab, " obj=%s", ctx);
-                                       security_release_secctx(ctx, len);
-                               }
-                       }
-                       break; }
-
                case AUDIT_IPC_SET_PERM: {
                        struct audit_aux_data_ipcctl *axi = (void *)aux;
                        audit_log_format(ab,
@@ -1427,7 +1423,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
        }
 
        if (context->type)
-               show_special(context);
+               show_special(context, &call_panic);
 
        if (context->sockaddr_len) {
                ab = audit_log_start(context, GFP_KERNEL, AUDIT_SOCKADDR);
@@ -2349,25 +2345,15 @@ int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
  * audit_ipc_obj - record audit data for ipc object
  * @ipcp: ipc permissions
  *
- * Returns 0 for success or NULL context or < 0 on error.
  */
-int __audit_ipc_obj(struct kern_ipc_perm *ipcp)
+void __audit_ipc_obj(struct kern_ipc_perm *ipcp)
 {
-       struct audit_aux_data_ipcctl *ax;
        struct audit_context *context = current->audit_context;
-
-       ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
-       if (!ax)
-               return -ENOMEM;
-
-       ax->uid = ipcp->uid;
-       ax->gid = ipcp->gid;
-       ax->mode = ipcp->mode;
-       security_ipc_getsecid(ipcp, &ax->osid);
-       ax->d.type = AUDIT_IPC;
-       ax->d.next = context->aux;
-       context->aux = (void *)ax;
-       return 0;
+       context->ipc.uid = ipcp->uid;
+       context->ipc.gid = ipcp->gid;
+       context->ipc.mode = ipcp->mode;
+       security_ipc_getsecid(ipcp, &context->ipc.osid);
+       context->type = AUDIT_IPC;
 }
 
 /**