diff options
Diffstat (limited to 'ipc/msg.c')
-rw-r--r-- | ipc/msg.c | 26 |
1 files changed, 14 insertions, 12 deletions
@@ -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 | */ |
185 | static void freeque (struct msg_queue *msq, int id) | 187 | static 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; |
491 | out_up: | 493 | out_up: |
492 | up(&msg_ids.sem); | 494 | mutex_unlock(&msg_ids.mutex); |
493 | return err; | 495 | return err; |
494 | out_unlock_up: | 496 | out_unlock_up: |
495 | msg_unlock(msq); | 497 | msg_unlock(msq); |