diff options
Diffstat (limited to 'ipc/sem.c')
-rw-r--r-- | ipc/sem.c | 38 |
1 files changed, 16 insertions, 22 deletions
@@ -617,8 +617,8 @@ static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in, | |||
617 | } | 617 | } |
618 | } | 618 | } |
619 | 619 | ||
620 | static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum, | 620 | static int semctl_nolock(struct ipc_namespace *ns, int semid, |
621 | int cmd, int version, union semun arg) | 621 | int cmd, int version, union semun arg) |
622 | { | 622 | { |
623 | int err = -EINVAL; | 623 | int err = -EINVAL; |
624 | struct sem_array *sma; | 624 | struct sem_array *sma; |
@@ -657,14 +657,23 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum, | |||
657 | return -EFAULT; | 657 | return -EFAULT; |
658 | return (max_id < 0) ? 0: max_id; | 658 | return (max_id < 0) ? 0: max_id; |
659 | } | 659 | } |
660 | case IPC_STAT: | ||
660 | case SEM_STAT: | 661 | case SEM_STAT: |
661 | { | 662 | { |
662 | struct semid64_ds tbuf; | 663 | struct semid64_ds tbuf; |
663 | int id; | 664 | int id; |
664 | 665 | ||
665 | sma = sem_lock(ns, semid); | 666 | if (cmd == SEM_STAT) { |
666 | if (IS_ERR(sma)) | 667 | sma = sem_lock(ns, semid); |
667 | return PTR_ERR(sma); | 668 | if (IS_ERR(sma)) |
669 | return PTR_ERR(sma); | ||
670 | id = sma->sem_perm.id; | ||
671 | } else { | ||
672 | sma = sem_lock_check(ns, semid); | ||
673 | if (IS_ERR(sma)) | ||
674 | return PTR_ERR(sma); | ||
675 | id = 0; | ||
676 | } | ||
668 | 677 | ||
669 | err = -EACCES; | 678 | err = -EACCES; |
670 | if (ipcperms (&sma->sem_perm, S_IRUGO)) | 679 | if (ipcperms (&sma->sem_perm, S_IRUGO)) |
@@ -674,8 +683,6 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum, | |||
674 | if (err) | 683 | if (err) |
675 | goto out_unlock; | 684 | goto out_unlock; |
676 | 685 | ||
677 | id = sma->sem_perm.id; | ||
678 | |||
679 | memset(&tbuf, 0, sizeof(tbuf)); | 686 | memset(&tbuf, 0, sizeof(tbuf)); |
680 | 687 | ||
681 | kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm); | 688 | kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm); |
@@ -810,19 +817,6 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum, | |||
810 | err = 0; | 817 | err = 0; |
811 | goto out_unlock; | 818 | goto out_unlock; |
812 | } | 819 | } |
813 | case IPC_STAT: | ||
814 | { | ||
815 | struct semid64_ds tbuf; | ||
816 | memset(&tbuf,0,sizeof(tbuf)); | ||
817 | kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm); | ||
818 | tbuf.sem_otime = sma->sem_otime; | ||
819 | tbuf.sem_ctime = sma->sem_ctime; | ||
820 | tbuf.sem_nsems = sma->sem_nsems; | ||
821 | sem_unlock(sma); | ||
822 | if (copy_semid_to_user (arg.buf, &tbuf, version)) | ||
823 | return -EFAULT; | ||
824 | return 0; | ||
825 | } | ||
826 | /* GETVAL, GETPID, GETNCTN, GETZCNT, SETVAL: fall-through */ | 820 | /* GETVAL, GETPID, GETNCTN, GETZCNT, SETVAL: fall-through */ |
827 | } | 821 | } |
828 | err = -EINVAL; | 822 | err = -EINVAL; |
@@ -989,15 +983,15 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg) | |||
989 | switch(cmd) { | 983 | switch(cmd) { |
990 | case IPC_INFO: | 984 | case IPC_INFO: |
991 | case SEM_INFO: | 985 | case SEM_INFO: |
986 | case IPC_STAT: | ||
992 | case SEM_STAT: | 987 | case SEM_STAT: |
993 | err = semctl_nolock(ns,semid,semnum,cmd,version,arg); | 988 | err = semctl_nolock(ns, semid, cmd, version, arg); |
994 | return err; | 989 | return err; |
995 | case GETALL: | 990 | case GETALL: |
996 | case GETVAL: | 991 | case GETVAL: |
997 | case GETPID: | 992 | case GETPID: |
998 | case GETNCNT: | 993 | case GETNCNT: |
999 | case GETZCNT: | 994 | case GETZCNT: |
1000 | case IPC_STAT: | ||
1001 | case SETVAL: | 995 | case SETVAL: |
1002 | case SETALL: | 996 | case SETALL: |
1003 | err = semctl_main(ns,semid,semnum,cmd,version,arg); | 997 | err = semctl_main(ns,semid,semnum,cmd,version,arg); |