diff options
Diffstat (limited to 'ipc/msg.c')
-rw-r--r-- | ipc/msg.c | 51 |
1 files changed, 18 insertions, 33 deletions
@@ -388,31 +388,14 @@ copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version) | |||
388 | } | 388 | } |
389 | } | 389 | } |
390 | 390 | ||
391 | struct msq_setbuf { | ||
392 | unsigned long qbytes; | ||
393 | uid_t uid; | ||
394 | gid_t gid; | ||
395 | mode_t mode; | ||
396 | }; | ||
397 | |||
398 | static inline unsigned long | 391 | static inline unsigned long |
399 | copy_msqid_from_user(struct msq_setbuf *out, void __user *buf, int version) | 392 | copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version) |
400 | { | 393 | { |
401 | switch(version) { | 394 | switch(version) { |
402 | case IPC_64: | 395 | case IPC_64: |
403 | { | 396 | if (copy_from_user(out, buf, sizeof(*out))) |
404 | struct msqid64_ds tbuf; | ||
405 | |||
406 | if (copy_from_user(&tbuf, buf, sizeof(tbuf))) | ||
407 | return -EFAULT; | 397 | return -EFAULT; |
408 | |||
409 | out->qbytes = tbuf.msg_qbytes; | ||
410 | out->uid = tbuf.msg_perm.uid; | ||
411 | out->gid = tbuf.msg_perm.gid; | ||
412 | out->mode = tbuf.msg_perm.mode; | ||
413 | |||
414 | return 0; | 398 | return 0; |
415 | } | ||
416 | case IPC_OLD: | 399 | case IPC_OLD: |
417 | { | 400 | { |
418 | struct msqid_ds tbuf_old; | 401 | struct msqid_ds tbuf_old; |
@@ -420,14 +403,14 @@ copy_msqid_from_user(struct msq_setbuf *out, void __user *buf, int version) | |||
420 | if (copy_from_user(&tbuf_old, buf, sizeof(tbuf_old))) | 403 | if (copy_from_user(&tbuf_old, buf, sizeof(tbuf_old))) |
421 | return -EFAULT; | 404 | return -EFAULT; |
422 | 405 | ||
423 | out->uid = tbuf_old.msg_perm.uid; | 406 | out->msg_perm.uid = tbuf_old.msg_perm.uid; |
424 | out->gid = tbuf_old.msg_perm.gid; | 407 | out->msg_perm.gid = tbuf_old.msg_perm.gid; |
425 | out->mode = tbuf_old.msg_perm.mode; | 408 | out->msg_perm.mode = tbuf_old.msg_perm.mode; |
426 | 409 | ||
427 | if (tbuf_old.msg_qbytes == 0) | 410 | if (tbuf_old.msg_qbytes == 0) |
428 | out->qbytes = tbuf_old.msg_lqbytes; | 411 | out->msg_qbytes = tbuf_old.msg_lqbytes; |
429 | else | 412 | else |
430 | out->qbytes = tbuf_old.msg_qbytes; | 413 | out->msg_qbytes = tbuf_old.msg_qbytes; |
431 | 414 | ||
432 | return 0; | 415 | return 0; |
433 | } | 416 | } |
@@ -445,12 +428,12 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, | |||
445 | struct msqid_ds __user *buf, int version) | 428 | struct msqid_ds __user *buf, int version) |
446 | { | 429 | { |
447 | struct kern_ipc_perm *ipcp; | 430 | struct kern_ipc_perm *ipcp; |
448 | struct msq_setbuf setbuf; | 431 | struct msqid64_ds msqid64; |
449 | struct msg_queue *msq; | 432 | struct msg_queue *msq; |
450 | int err; | 433 | int err; |
451 | 434 | ||
452 | if (cmd == IPC_SET) { | 435 | if (cmd == IPC_SET) { |
453 | if (copy_msqid_from_user(&setbuf, buf, version)) | 436 | if (copy_msqid_from_user(&msqid64, buf, version)) |
454 | return -EFAULT; | 437 | return -EFAULT; |
455 | } | 438 | } |
456 | 439 | ||
@@ -468,8 +451,10 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, | |||
468 | goto out_unlock; | 451 | goto out_unlock; |
469 | 452 | ||
470 | if (cmd == IPC_SET) { | 453 | if (cmd == IPC_SET) { |
471 | err = audit_ipc_set_perm(setbuf.qbytes, setbuf.uid, setbuf.gid, | 454 | err = audit_ipc_set_perm(msqid64.msg_qbytes, |
472 | setbuf.mode); | 455 | msqid64.msg_perm.uid, |
456 | msqid64.msg_perm.gid, | ||
457 | msqid64.msg_perm.mode); | ||
473 | if (err) | 458 | if (err) |
474 | goto out_unlock; | 459 | goto out_unlock; |
475 | } | 460 | } |
@@ -491,18 +476,18 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, | |||
491 | freeque(ns, ipcp); | 476 | freeque(ns, ipcp); |
492 | goto out_up; | 477 | goto out_up; |
493 | case IPC_SET: | 478 | case IPC_SET: |
494 | if (setbuf.qbytes > ns->msg_ctlmnb && | 479 | if (msqid64.msg_qbytes > ns->msg_ctlmnb && |
495 | !capable(CAP_SYS_RESOURCE)) { | 480 | !capable(CAP_SYS_RESOURCE)) { |
496 | err = -EPERM; | 481 | err = -EPERM; |
497 | goto out_unlock; | 482 | goto out_unlock; |
498 | } | 483 | } |
499 | 484 | ||
500 | msq->q_qbytes = setbuf.qbytes; | 485 | msq->q_qbytes = msqid64.msg_qbytes; |
501 | 486 | ||
502 | ipcp->uid = setbuf.uid; | 487 | ipcp->uid = msqid64.msg_perm.uid; |
503 | ipcp->gid = setbuf.gid; | 488 | ipcp->gid = msqid64.msg_perm.gid; |
504 | ipcp->mode = (ipcp->mode & ~S_IRWXUGO) | | 489 | ipcp->mode = (ipcp->mode & ~S_IRWXUGO) | |
505 | (S_IRWXUGO & setbuf.mode); | 490 | (S_IRWXUGO & msqid64.msg_perm.mode); |
506 | msq->q_ctime = get_seconds(); | 491 | msq->q_ctime = get_seconds(); |
507 | /* sleeping receivers might be excluded by | 492 | /* sleeping receivers might be excluded by |
508 | * stricter permissions. | 493 | * stricter permissions. |