]> nv-tegra.nvidia Code Review - linux-3.10.git/blobdiff - ipc/msg.c
[ALSA] unregister platform device again if probe was unsuccessful
[linux-3.10.git] / ipc / msg.c
index d035bd2aba9671cc56fdd6f10b81182ac628b011..00f015a092d292347d781a60bf9f72c71b4381d1 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
  *
  * mostly rewritten, threaded and wake-one semantics added
  * MSGMAX limit removed, sysctl's added
- * (c) 1999 Manfred Spraul <manfreds@colorfullife.com>
+ * (c) 1999 Manfred Spraul <manfred@colorfullife.com>
+ *
+ * support for audit of ipc object properties and permission changes
+ * Dustin Kirkland <dustin.kirkland@us.ibm.com>
  */
 
+#include <linux/capability.h>
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/msg.h>
@@ -27,6 +31,8 @@
 #include <linux/syscalls.h>
 #include <linux/audit.h>
 #include <linux/seq_file.h>
+#include <linux/mutex.h>
+
 #include <asm/current.h>
 #include <asm/uaccess.h>
 #include "util.h"
@@ -178,8 +184,8 @@ static void expunge_all(struct msg_queue* msq, int res)
  * removes the message queue from message queue ID 
  * array, and cleans up all the messages associated with this queue.
  *
- * msg_ids.sem and the spinlock for this message queue is hold
- * before freeque() is called. msg_ids.sem remains locked on exit.
+ * msg_ids.mutex and the spinlock for this message queue is hold
+ * before freeque() is called. msg_ids.mutex remains locked on exit.
  */
 static void freeque (struct msg_queue *msq, int id)
 {
@@ -207,7 +213,7 @@ asmlinkage long sys_msgget (key_t key, int msgflg)
        int id, ret = -EPERM;
        struct msg_queue *msq;
        
-       down(&msg_ids.sem);
+       mutex_lock(&msg_ids.mutex);
        if (key == IPC_PRIVATE) 
                ret = newque(key, msgflg);
        else if ((id = ipc_findkey(&msg_ids, key)) == -1) { /* key not used */
@@ -219,8 +225,7 @@ asmlinkage long sys_msgget (key_t key, int msgflg)
                ret = -EEXIST;
        } else {
                msq = msg_lock(id);
-               if(msq==NULL)
-                       BUG();
+               BUG_ON(msq==NULL);
                if (ipcperms(&msq->q_perm, msgflg))
                        ret = -EACCES;
                else {
@@ -231,7 +236,7 @@ asmlinkage long sys_msgget (key_t key, int msgflg)
                }
                msg_unlock(msq);
        }
-       up(&msg_ids.sem);
+       mutex_unlock(&msg_ids.mutex);
        return ret;
 }
 
@@ -361,7 +366,7 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
                msginfo.msgmnb = msg_ctlmnb;
                msginfo.msgssz = MSGSSZ;
                msginfo.msgseg = MSGSEG;
-               down(&msg_ids.sem);
+               mutex_lock(&msg_ids.mutex);
                if (cmd == MSG_INFO) {
                        msginfo.msgpool = msg_ids.in_use;
                        msginfo.msgmap = atomic_read(&msg_hdrs);
@@ -372,7 +377,7 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
                        msginfo.msgtql = MSGTQL;
                }
                max_id = msg_ids.max_id;
-               up(&msg_ids.sem);
+               mutex_unlock(&msg_ids.mutex);
                if (copy_to_user (buf, &msginfo, sizeof(struct msginfo)))
                        return -EFAULT;
                return (max_id < 0) ? 0: max_id;
@@ -428,8 +433,6 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
                        return -EFAULT;
                if (copy_msqid_from_user (&setbuf, buf, version))
                        return -EFAULT;
-               if ((err = audit_ipc_perms(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode)))
-                       return err;
                break;
        case IPC_RMID:
                break;
@@ -437,7 +440,7 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
                return  -EINVAL;
        }
 
-       down(&msg_ids.sem);
+       mutex_lock(&msg_ids.mutex);
        msq = msg_lock(msqid);
        err=-EINVAL;
        if (msq == NULL)
@@ -447,6 +450,16 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
        if (msg_checkid(msq,msqid))
                goto out_unlock_up;
        ipcp = &msq->q_perm;
+
+       err = audit_ipc_obj(ipcp);
+       if (err)
+               goto out_unlock_up;
+       if (cmd==IPC_SET) {
+               err = audit_ipc_set_perm(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode);
+               if (err)
+                       goto out_unlock_up;
+       }
+
        err = -EPERM;
        if (current->euid != ipcp->cuid && 
            current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN))
@@ -488,7 +501,7 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
        }
        err = 0;
 out_up:
-       up(&msg_ids.sem);
+       mutex_unlock(&msg_ids.mutex);
        return err;
 out_unlock_up:
        msg_unlock(msq);