aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/msg.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/msg.c')
-rw-r--r--ipc/msg.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/ipc/msg.c b/ipc/msg.c
index fbf757064a32..48a7f17a7236 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -28,6 +28,8 @@
28#include <linux/syscalls.h> 28#include <linux/syscalls.h>
29#include <linux/audit.h> 29#include <linux/audit.h>
30#include <linux/seq_file.h> 30#include <linux/seq_file.h>
31#include <linux/mutex.h>
32
31#include <asm/current.h> 33#include <asm/current.h>
32#include <asm/uaccess.h> 34#include <asm/uaccess.h>
33#include "util.h" 35#include "util.h"
@@ -179,8 +181,8 @@ static void expunge_all(struct msg_queue* msq, int res)
179 * removes the message queue from message queue ID 181 * removes the message queue from message queue ID
180 * array, and cleans up all the messages associated with this queue. 182 * array, and cleans up all the messages associated with this queue.
181 * 183 *
182 * msg_ids.sem and the spinlock for this message queue is hold 184 * msg_ids.mutex and the spinlock for this message queue is hold
183 * before freeque() is called. msg_ids.sem remains locked on exit. 185 * before freeque() is called. msg_ids.mutex remains locked on exit.
184 */ 186 */
185static void freeque (struct msg_queue *msq, int id) 187static void freeque (struct msg_queue *msq, int id)
186{ 188{
@@ -208,7 +210,7 @@ asmlinkage long sys_msgget (key_t key, int msgflg)
208 int id, ret = -EPERM; 210 int id, ret = -EPERM;
209 struct msg_queue *msq; 211 struct msg_queue *msq;
210 212
211 down(&msg_ids.sem); 213 mutex_lock(&msg_ids.mutex);
212 if (key == IPC_PRIVATE) 214 if (key == IPC_PRIVATE)
213 ret = newque(key, msgflg); 215 ret = newque(key, msgflg);
214 else if ((id = ipc_findkey(&msg_ids, key)) == -1) { /* key not used */ 216 else if ((id = ipc_findkey(&msg_ids, key)) == -1) { /* key not used */
@@ -220,8 +222,7 @@ asmlinkage long sys_msgget (key_t key, int msgflg)
220 ret = -EEXIST; 222 ret = -EEXIST;
221 } else { 223 } else {
222 msq = msg_lock(id); 224 msq = msg_lock(id);
223 if(msq==NULL) 225 BUG_ON(msq==NULL);
224 BUG();
225 if (ipcperms(&msq->q_perm, msgflg)) 226 if (ipcperms(&msq->q_perm, msgflg))
226 ret = -EACCES; 227 ret = -EACCES;
227 else { 228 else {
@@ -232,7 +233,7 @@ asmlinkage long sys_msgget (key_t key, int msgflg)
232 } 233 }
233 msg_unlock(msq); 234 msg_unlock(msq);
234 } 235 }
235 up(&msg_ids.sem); 236 mutex_unlock(&msg_ids.mutex);
236 return ret; 237 return ret;
237} 238}
238 239
@@ -362,7 +363,7 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
362 msginfo.msgmnb = msg_ctlmnb; 363 msginfo.msgmnb = msg_ctlmnb;
363 msginfo.msgssz = MSGSSZ; 364 msginfo.msgssz = MSGSSZ;
364 msginfo.msgseg = MSGSEG; 365 msginfo.msgseg = MSGSEG;
365 down(&msg_ids.sem); 366 mutex_lock(&msg_ids.mutex);
366 if (cmd == MSG_INFO) { 367 if (cmd == MSG_INFO) {
367 msginfo.msgpool = msg_ids.in_use; 368 msginfo.msgpool = msg_ids.in_use;
368 msginfo.msgmap = atomic_read(&msg_hdrs); 369 msginfo.msgmap = atomic_read(&msg_hdrs);
@@ -373,7 +374,7 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
373 msginfo.msgtql = MSGTQL; 374 msginfo.msgtql = MSGTQL;
374 } 375 }
375 max_id = msg_ids.max_id; 376 max_id = msg_ids.max_id;
376 up(&msg_ids.sem); 377 mutex_unlock(&msg_ids.mutex);
377 if (copy_to_user (buf, &msginfo, sizeof(struct msginfo))) 378 if (copy_to_user (buf, &msginfo, sizeof(struct msginfo)))
378 return -EFAULT; 379 return -EFAULT;
379 return (max_id < 0) ? 0: max_id; 380 return (max_id < 0) ? 0: max_id;
@@ -429,8 +430,6 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
429 return -EFAULT; 430 return -EFAULT;
430 if (copy_msqid_from_user (&setbuf, buf, version)) 431 if (copy_msqid_from_user (&setbuf, buf, version))
431 return -EFAULT; 432 return -EFAULT;
432 if ((err = audit_ipc_perms(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode)))
433 return err;
434 break; 433 break;
435 case IPC_RMID: 434 case IPC_RMID:
436 break; 435 break;
@@ -438,7 +437,7 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
438 return -EINVAL; 437 return -EINVAL;
439 } 438 }
440 439
441 down(&msg_ids.sem); 440 mutex_lock(&msg_ids.mutex);
442 msq = msg_lock(msqid); 441 msq = msg_lock(msqid);
443 err=-EINVAL; 442 err=-EINVAL;
444 if (msq == NULL) 443 if (msq == NULL)
@@ -461,6 +460,9 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
461 switch (cmd) { 460 switch (cmd) {
462 case IPC_SET: 461 case IPC_SET:
463 { 462 {
463 if ((err = audit_ipc_perms(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode, ipcp)))
464 goto out_unlock_up;
465
464 err = -EPERM; 466 err = -EPERM;
465 if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE)) 467 if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE))
466 goto out_unlock_up; 468 goto out_unlock_up;
@@ -489,7 +491,7 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
489 } 491 }
490 err = 0; 492 err = 0;
491out_up: 493out_up:
492 up(&msg_ids.sem); 494 mutex_unlock(&msg_ids.mutex);
493 return err; 495 return err;
494out_unlock_up: 496out_unlock_up:
495 msg_unlock(msq); 497 msg_unlock(msq);