summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2017-01-23 23:22:00 +0000
committermpi <mpi@openbsd.org>2017-01-23 23:22:00 +0000
commit99f4395a92357dec2f9cfce05f5356f40aefd487 (patch)
treef11b8a4ce0e0dd88bc4b2c859349b4f819a14dbb /sys/kern
parentFor testing http redirect unset http_proxy, not ftp_proxy. (diff)
downloadwireguard-openbsd-99f4395a92357dec2f9cfce05f5356f40aefd487.tar.xz
wireguard-openbsd-99f4395a92357dec2f9cfce05f5356f40aefd487.zip
Allocate all memory chunks, and potentially sleeping, before freeing
the old array of open files. Fix a race for multi-threaded processes reported by cheeky.m@gmx.com on bugs@ and analyzed with bluhm@. ok deraadt@, bluhm@
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_descrip.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index e4b44839b37..904f7b43439 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_descrip.c,v 1.137 2017/01/23 22:34:10 deraadt Exp $ */
+/* $OpenBSD: kern_descrip.c,v 1.138 2017/01/23 23:22:00 mpi Exp $ */
/* $NetBSD: kern_descrip.c,v 1.42 1996/03/30 22:24:38 christos Exp $ */
/*
@@ -835,6 +835,16 @@ fdexpand(struct proc *p)
nfiles = 2 * fdp->fd_nfiles;
newofile = mallocarray(nfiles, OFILESIZE, M_FILEDESC, M_WAITOK);
+ /*
+ * Allocate all required chunks before calling free(9) to make
+ * sure that ``fd_ofiles'' stays valid if we go to sleep.
+ */
+ if (NDHISLOTS(nfiles) > NDHISLOTS(fdp->fd_nfiles)) {
+ newhimap = mallocarray(NDHISLOTS(nfiles), sizeof(u_int),
+ M_FILEDESC, M_WAITOK);
+ newlomap = mallocarray(NDLOSLOTS(nfiles), sizeof(u_int),
+ M_FILEDESC, M_WAITOK);
+ }
newofileflags = (char *) &newofile[nfiles];
/*
@@ -853,11 +863,6 @@ fdexpand(struct proc *p)
free(fdp->fd_ofiles, M_FILEDESC, fdp->fd_nfiles * OFILESIZE);
if (NDHISLOTS(nfiles) > NDHISLOTS(fdp->fd_nfiles)) {
- newhimap = mallocarray(NDHISLOTS(nfiles), sizeof(u_int),
- M_FILEDESC, M_WAITOK);
- newlomap = mallocarray(NDLOSLOTS(nfiles), sizeof(u_int),
- M_FILEDESC, M_WAITOK);
-
copylen = NDHISLOTS(fdp->fd_nfiles) * sizeof(u_int);
memcpy(newhimap, fdp->fd_himap, copylen);
memset((char *)newhimap + copylen, 0,