diff options
-rw-r--r-- | ipc/msg.c | 51 | ||||
-rw-r--r-- | ipc/sem.c | 40 | ||||
-rw-r--r-- | ipc/shm.c | 41 |
3 files changed, 46 insertions, 86 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. |
@@ -835,28 +835,14 @@ out_free: | |||
835 | return err; | 835 | return err; |
836 | } | 836 | } |
837 | 837 | ||
838 | struct sem_setbuf { | 838 | static inline unsigned long |
839 | uid_t uid; | 839 | copy_semid_from_user(struct semid64_ds *out, void __user *buf, int version) |
840 | gid_t gid; | ||
841 | mode_t mode; | ||
842 | }; | ||
843 | |||
844 | static inline unsigned long copy_semid_from_user(struct sem_setbuf *out, void __user *buf, int version) | ||
845 | { | 840 | { |
846 | switch(version) { | 841 | switch(version) { |
847 | case IPC_64: | 842 | case IPC_64: |
848 | { | 843 | if (copy_from_user(out, buf, sizeof(*out))) |
849 | struct semid64_ds tbuf; | ||
850 | |||
851 | if(copy_from_user(&tbuf, buf, sizeof(tbuf))) | ||
852 | return -EFAULT; | 844 | return -EFAULT; |
853 | |||
854 | out->uid = tbuf.sem_perm.uid; | ||
855 | out->gid = tbuf.sem_perm.gid; | ||
856 | out->mode = tbuf.sem_perm.mode; | ||
857 | |||
858 | return 0; | 845 | return 0; |
859 | } | ||
860 | case IPC_OLD: | 846 | case IPC_OLD: |
861 | { | 847 | { |
862 | struct semid_ds tbuf_old; | 848 | struct semid_ds tbuf_old; |
@@ -864,9 +850,9 @@ static inline unsigned long copy_semid_from_user(struct sem_setbuf *out, void __ | |||
864 | if(copy_from_user(&tbuf_old, buf, sizeof(tbuf_old))) | 850 | if(copy_from_user(&tbuf_old, buf, sizeof(tbuf_old))) |
865 | return -EFAULT; | 851 | return -EFAULT; |
866 | 852 | ||
867 | out->uid = tbuf_old.sem_perm.uid; | 853 | out->sem_perm.uid = tbuf_old.sem_perm.uid; |
868 | out->gid = tbuf_old.sem_perm.gid; | 854 | out->sem_perm.gid = tbuf_old.sem_perm.gid; |
869 | out->mode = tbuf_old.sem_perm.mode; | 855 | out->sem_perm.mode = tbuf_old.sem_perm.mode; |
870 | 856 | ||
871 | return 0; | 857 | return 0; |
872 | } | 858 | } |
@@ -885,11 +871,11 @@ static int semctl_down(struct ipc_namespace *ns, int semid, | |||
885 | { | 871 | { |
886 | struct sem_array *sma; | 872 | struct sem_array *sma; |
887 | int err; | 873 | int err; |
888 | struct sem_setbuf uninitialized_var(setbuf); | 874 | struct semid64_ds semid64; |
889 | struct kern_ipc_perm *ipcp; | 875 | struct kern_ipc_perm *ipcp; |
890 | 876 | ||
891 | if(cmd == IPC_SET) { | 877 | if(cmd == IPC_SET) { |
892 | if(copy_semid_from_user (&setbuf, arg.buf, version)) | 878 | if (copy_semid_from_user(&semid64, arg.buf, version)) |
893 | return -EFAULT; | 879 | return -EFAULT; |
894 | } | 880 | } |
895 | down_write(&sem_ids(ns).rw_mutex); | 881 | down_write(&sem_ids(ns).rw_mutex); |
@@ -906,7 +892,9 @@ static int semctl_down(struct ipc_namespace *ns, int semid, | |||
906 | goto out_unlock; | 892 | goto out_unlock; |
907 | 893 | ||
908 | if (cmd == IPC_SET) { | 894 | if (cmd == IPC_SET) { |
909 | err = audit_ipc_set_perm(0, setbuf.uid, setbuf.gid, setbuf.mode); | 895 | err = audit_ipc_set_perm(0, semid64.sem_perm.uid, |
896 | semid64.sem_perm.gid, | ||
897 | semid64.sem_perm.mode); | ||
910 | if (err) | 898 | if (err) |
911 | goto out_unlock; | 899 | goto out_unlock; |
912 | } | 900 | } |
@@ -925,10 +913,10 @@ static int semctl_down(struct ipc_namespace *ns, int semid, | |||
925 | freeary(ns, ipcp); | 913 | freeary(ns, ipcp); |
926 | goto out_up; | 914 | goto out_up; |
927 | case IPC_SET: | 915 | case IPC_SET: |
928 | ipcp->uid = setbuf.uid; | 916 | ipcp->uid = semid64.sem_perm.uid; |
929 | ipcp->gid = setbuf.gid; | 917 | ipcp->gid = semid64.sem_perm.gid; |
930 | ipcp->mode = (ipcp->mode & ~S_IRWXUGO) | 918 | ipcp->mode = (ipcp->mode & ~S_IRWXUGO) |
931 | | (setbuf.mode & S_IRWXUGO); | 919 | | (semid64.sem_perm.mode & S_IRWXUGO); |
932 | sma->sem_ctime = get_seconds(); | 920 | sma->sem_ctime = get_seconds(); |
933 | break; | 921 | break; |
934 | default: | 922 | default: |
@@ -511,28 +511,14 @@ static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ | |||
511 | } | 511 | } |
512 | } | 512 | } |
513 | 513 | ||
514 | struct shm_setbuf { | 514 | static inline unsigned long |
515 | uid_t uid; | 515 | copy_shmid_from_user(struct shmid64_ds *out, void __user *buf, int version) |
516 | gid_t gid; | ||
517 | mode_t mode; | ||
518 | }; | ||
519 | |||
520 | static inline unsigned long copy_shmid_from_user(struct shm_setbuf *out, void __user *buf, int version) | ||
521 | { | 516 | { |
522 | switch(version) { | 517 | switch(version) { |
523 | case IPC_64: | 518 | case IPC_64: |
524 | { | 519 | if (copy_from_user(out, buf, sizeof(*out))) |
525 | struct shmid64_ds tbuf; | ||
526 | |||
527 | if (copy_from_user(&tbuf, buf, sizeof(tbuf))) | ||
528 | return -EFAULT; | 520 | return -EFAULT; |
529 | |||
530 | out->uid = tbuf.shm_perm.uid; | ||
531 | out->gid = tbuf.shm_perm.gid; | ||
532 | out->mode = tbuf.shm_perm.mode; | ||
533 | |||
534 | return 0; | 521 | return 0; |
535 | } | ||
536 | case IPC_OLD: | 522 | case IPC_OLD: |
537 | { | 523 | { |
538 | struct shmid_ds tbuf_old; | 524 | struct shmid_ds tbuf_old; |
@@ -540,9 +526,9 @@ static inline unsigned long copy_shmid_from_user(struct shm_setbuf *out, void __ | |||
540 | if (copy_from_user(&tbuf_old, buf, sizeof(tbuf_old))) | 526 | if (copy_from_user(&tbuf_old, buf, sizeof(tbuf_old))) |
541 | return -EFAULT; | 527 | return -EFAULT; |
542 | 528 | ||
543 | out->uid = tbuf_old.shm_perm.uid; | 529 | out->shm_perm.uid = tbuf_old.shm_perm.uid; |
544 | out->gid = tbuf_old.shm_perm.gid; | 530 | out->shm_perm.gid = tbuf_old.shm_perm.gid; |
545 | out->mode = tbuf_old.shm_perm.mode; | 531 | out->shm_perm.mode = tbuf_old.shm_perm.mode; |
546 | 532 | ||
547 | return 0; | 533 | return 0; |
548 | } | 534 | } |
@@ -625,12 +611,12 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd, | |||
625 | struct shmid_ds __user *buf, int version) | 611 | struct shmid_ds __user *buf, int version) |
626 | { | 612 | { |
627 | struct kern_ipc_perm *ipcp; | 613 | struct kern_ipc_perm *ipcp; |
628 | struct shm_setbuf setbuf; | 614 | struct shmid64_ds shmid64; |
629 | struct shmid_kernel *shp; | 615 | struct shmid_kernel *shp; |
630 | int err; | 616 | int err; |
631 | 617 | ||
632 | if (cmd == IPC_SET) { | 618 | if (cmd == IPC_SET) { |
633 | if (copy_shmid_from_user(&setbuf, buf, version)) | 619 | if (copy_shmid_from_user(&shmid64, buf, version)) |
634 | return -EFAULT; | 620 | return -EFAULT; |
635 | } | 621 | } |
636 | 622 | ||
@@ -648,8 +634,9 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd, | |||
648 | goto out_unlock; | 634 | goto out_unlock; |
649 | 635 | ||
650 | if (cmd == IPC_SET) { | 636 | if (cmd == IPC_SET) { |
651 | err = audit_ipc_set_perm(0, setbuf.uid, | 637 | err = audit_ipc_set_perm(0, shmid64.shm_perm.uid, |
652 | setbuf.gid, setbuf.mode); | 638 | shmid64.shm_perm.gid, |
639 | shmid64.shm_perm.mode); | ||
653 | if (err) | 640 | if (err) |
654 | goto out_unlock; | 641 | goto out_unlock; |
655 | } | 642 | } |
@@ -669,10 +656,10 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd, | |||
669 | do_shm_rmid(ns, ipcp); | 656 | do_shm_rmid(ns, ipcp); |
670 | goto out_up; | 657 | goto out_up; |
671 | case IPC_SET: | 658 | case IPC_SET: |
672 | ipcp->uid = setbuf.uid; | 659 | ipcp->uid = shmid64.shm_perm.uid; |
673 | ipcp->gid = setbuf.gid; | 660 | ipcp->gid = shmid64.shm_perm.gid; |
674 | ipcp->mode = (ipcp->mode & ~S_IRWXUGO) | 661 | ipcp->mode = (ipcp->mode & ~S_IRWXUGO) |
675 | | (setbuf.mode & S_IRWXUGO); | 662 | | (shmid64.shm_perm.mode & S_IRWXUGO); |
676 | shp->shm_ctim = get_seconds(); | 663 | shp->shm_ctim = get_seconds(); |
677 | break; | 664 | break; |
678 | default: | 665 | default: |