diff options
Diffstat (limited to 'ipc/shm.c')
-rw-r--r-- | ipc/shm.c | 41 |
1 files changed, 14 insertions, 27 deletions
@@ -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: |