diff options
author | kib <kib@FreeBSD.org> | 2015-05-04 08:13:05 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2015-05-04 08:13:05 +0000 |
commit | d84bf0ab22919c7aa4f6c901db42986e03705b53 (patch) | |
tree | 8cc983a16ae0c2ac6fbc8418f363d99ba3d8d367 /sys/kern | |
parent | 5947b2ef7f635baabe04d4b470edf1e36e7cd956 (diff) | |
download | FreeBSD-src-d84bf0ab22919c7aa4f6c901db42986e03705b53.zip FreeBSD-src-d84bf0ab22919c7aa4f6c901db42986e03705b53.tar.gz |
MFC r282084:
Fix locking for oshmctl() and shmsys().
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/sysv_shm.c | 50 |
1 files changed, 24 insertions, 26 deletions
diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index a5095b8..66a2a43 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -967,39 +967,39 @@ oshmctl(struct thread *td, struct oshmctl_args *uap) if (!prison_allow(td->td_ucred, PR_ALLOW_SYSVIPC)) return (ENOSYS); + if (uap->cmd != IPC_STAT) { + return (freebsd7_shmctl(td, + (struct freebsd7_shmctl_args *)uap)); + } SYSVSHM_LOCK(); shmseg = shm_find_segment(uap->shmid, true); if (shmseg == NULL) { SYSVSHM_UNLOCK(); return (EINVAL); } - switch (uap->cmd) { - case IPC_STAT: - error = ipcperm(td, &shmseg->u.shm_perm, IPC_R); - if (error != 0) - break; + error = ipcperm(td, &shmseg->u.shm_perm, IPC_R); + if (error != 0) { + SYSVSHM_UNLOCK(); + return (error); + } #ifdef MAC - error = mac_sysvshm_check_shmctl(td->td_ucred, shmseg, - uap->cmd); - if (error != 0) - break; -#endif - ipcperm_new2old(&shmseg->u.shm_perm, &outbuf.shm_perm); - outbuf.shm_segsz = shmseg->u.shm_segsz; - outbuf.shm_cpid = shmseg->u.shm_cpid; - outbuf.shm_lpid = shmseg->u.shm_lpid; - outbuf.shm_nattch = shmseg->u.shm_nattch; - outbuf.shm_atime = shmseg->u.shm_atime; - outbuf.shm_dtime = shmseg->u.shm_dtime; - outbuf.shm_ctime = shmseg->u.shm_ctime; - outbuf.shm_handle = shmseg->object; - error = copyout(&outbuf, uap->ubuf, sizeof(outbuf)); - break; - default: - error = freebsd7_shmctl(td, (struct freebsd7_shmctl_args *)uap); - break; + error = mac_sysvshm_check_shmctl(td->td_ucred, shmseg, uap->cmd); + if (error != 0) { + SYSVSHM_UNLOCK(); + return (error); } +#endif + ipcperm_new2old(&shmseg->u.shm_perm, &outbuf.shm_perm); + outbuf.shm_segsz = shmseg->u.shm_segsz; + outbuf.shm_cpid = shmseg->u.shm_cpid; + outbuf.shm_lpid = shmseg->u.shm_lpid; + outbuf.shm_nattch = shmseg->u.shm_nattch; + outbuf.shm_atime = shmseg->u.shm_atime; + outbuf.shm_dtime = shmseg->u.shm_dtime; + outbuf.shm_ctime = shmseg->u.shm_ctime; + outbuf.shm_handle = shmseg->object; SYSVSHM_UNLOCK(); + error = copyout(&outbuf, uap->ubuf, sizeof(outbuf)); return (error); #else return (EINVAL); @@ -1031,9 +1031,7 @@ sys_shmsys(struct thread *td, struct shmsys_args *uap) return (ENOSYS); if (uap->which < 0 || uap->which >= nitems(shmcalls)) return (EINVAL); - SYSVSHM_LOCK(); error = (*shmcalls[uap->which])(td, &uap->a2); - SYSVSHM_UNLOCK(); return (error); } |