diff options
author | 2019-10-28 19:57:50 +0000 | |
---|---|---|
committer | 2019-10-28 19:57:50 +0000 | |
commit | d13730a2799315653da786c7fbdabe600367c0ad (patch) | |
tree | d14c70e234a854cb7ae99841245ada4034ab8668 | |
parent | Have iwm(4) configure the PCIe LTR. (diff) | |
download | wireguard-openbsd-d13730a2799315653da786c7fbdabe600367c0ad.tar.xz wireguard-openbsd-d13730a2799315653da786c7fbdabe600367c0ad.zip |
Copy in the user-supplied buffer in shmctl(2) before looking up the
shared memory segment. Otherwise, if copyin ends up sleeping it allows
another thread to remove the same segment leading to a use-after-free.
Feedback from kettenis@ and ok guenther@
Reported-by: syzbot+0de42c2e600a6dd3091d@syzkaller.appspotmail.com
-rw-r--r-- | sys/kern/sysv_shm.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index 1fcaff75b9f..c64112f8f72 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sysv_shm.c,v 1.71 2019/01/25 00:19:26 millert Exp $ */ +/* $OpenBSD: sysv_shm.c,v 1.72 2019/10/28 19:57:50 anton Exp $ */ /* $NetBSD: sysv_shm.c,v 1.50 1998/10/21 22:24:29 tron Exp $ */ /* @@ -302,6 +302,12 @@ shmctl1(struct proc *p, int shmid, int cmd, caddr_t buf, struct shmid_ds inbuf, *shmseg; int error; + if (cmd == IPC_SET) { + error = ds_copyin(buf, &inbuf, sizeof(inbuf)); + if (error) + return (error); + } + shmseg = shm_find_segment_by_shmid(shmid); if (shmseg == NULL) return (EINVAL); @@ -316,9 +322,6 @@ shmctl1(struct proc *p, int shmid, int cmd, caddr_t buf, case IPC_SET: if ((error = ipcperm(cred, &shmseg->shm_perm, IPC_M)) != 0) return (error); - error = ds_copyin(buf, &inbuf, sizeof(inbuf)); - if (error) - return (error); shmseg->shm_perm.uid = inbuf.shm_perm.uid; shmseg->shm_perm.gid = inbuf.shm_perm.gid; shmseg->shm_perm.mode = |