#define audit_get_sessionid(t) ((t)->sessionid)
 extern void audit_log_task_context(struct audit_buffer *ab);
 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 void __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);
 extern int audit_sockaddr(int len, void *addr);
                return __audit_fd_pair(fd1, fd2);
        return 0;
 }
-static inline int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
+static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
 {
        if (unlikely(!audit_dummy_context()))
-               return __audit_ipc_set_perm(qbytes, uid, gid, mode);
-       return 0;
+               __audit_ipc_set_perm(qbytes, uid, gid, mode);
 }
 static inline int audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr)
 {
 #define audit_get_sessionid(t) (-1)
 #define audit_log_task_context(b) do { ; } while (0)
 #define audit_ipc_obj(i) ((void)0)
-#define audit_ipc_set_perm(q,u,g,m) ({ 0; })
+#define audit_ipc_set_perm(q,u,g,m) ((void)0)
 #define audit_bprm(p) ({ 0; })
 #define audit_socketcall(n,a) ((void)0)
 #define audit_fd_pair(n,a) ({ 0; })
 
        struct mq_attr          mqstat;
 };
 
-struct audit_aux_data_ipcctl {
-       struct audit_aux_data   d;
-       struct ipc_perm         p;
-       unsigned long           qbytes;
-       uid_t                   uid;
-       gid_t                   gid;
-       mode_t                  mode;
-       u32                     osid;
-};
-
 struct audit_aux_data_execve {
        struct audit_aux_data   d;
        int argc;
                        gid_t                   gid;
                        mode_t                  mode;
                        u32                     osid;
+                       int                     has_perm;
+                       uid_t                   perm_uid;
+                       gid_t                   perm_gid;
+                       mode_t                  perm_mode;
+                       unsigned long           qbytes;
                } ipc;
        };
 
                                security_release_secctx(ctx, len);
                        }
                }
+               if (context->ipc.has_perm) {
+                       audit_log_end(ab);
+                       ab = audit_log_start(context, GFP_KERNEL,
+                                            AUDIT_IPC_SET_PERM);
+                       audit_log_format(ab,
+                               "qbytes=%lx ouid=%u ogid=%u mode=%#o",
+                               context->ipc.qbytes,
+                               context->ipc.perm_uid,
+                               context->ipc.perm_gid,
+                               context->ipc.perm_mode);
+                       if (!ab)
+                               return;
+               }
                break; }
        }
        audit_log_end(ab);
                                axi->mqstat.mq_msgsize, axi->mqstat.mq_curmsgs);
                        break; }
 
-               case AUDIT_IPC_SET_PERM: {
-                       struct audit_aux_data_ipcctl *axi = (void *)aux;
-                       audit_log_format(ab,
-                               "qbytes=%lx ouid=%u ogid=%u mode=%#o",
-                               axi->qbytes, axi->uid, axi->gid, axi->mode);
-                       break; }
-
                case AUDIT_EXECVE: {
                        struct audit_aux_data_execve *axi = (void *)aux;
                        audit_log_execve_info(context, &ab, axi);
        context->ipc.uid = ipcp->uid;
        context->ipc.gid = ipcp->gid;
        context->ipc.mode = ipcp->mode;
+       context->ipc.has_perm = 0;
        security_ipc_getsecid(ipcp, &context->ipc.osid);
        context->type = AUDIT_IPC;
 }
  * @gid: msgq group id
  * @mode: msgq mode (permissions)
  *
- * Returns 0 for success or NULL context or < 0 on error.
+ * Called only after audit_ipc_obj().
  */
-int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
+void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
 {
-       struct audit_aux_data_ipcctl *ax;
        struct audit_context *context = current->audit_context;
 
-       ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
-       if (!ax)
-               return -ENOMEM;
-
-       ax->qbytes = qbytes;
-       ax->uid = uid;
-       ax->gid = gid;
-       ax->mode = mode;
-
-       ax->d.type = AUDIT_IPC_SET_PERM;
-       ax->d.next = context->aux;
-       context->aux = (void *)ax;
-       return 0;
+       context->ipc.qbytes = qbytes;
+       context->ipc.perm_uid = uid;
+       context->ipc.perm_gid = gid;
+       context->ipc.perm_mode = mode;
+       context->ipc.has_perm = 1;
 }
 
 int audit_bprm(struct linux_binprm *bprm)