diff options
| author | 2020-06-11 13:23:18 +0000 | |
|---|---|---|
| committer | 2020-06-11 13:23:18 +0000 | |
| commit | 484822295e51fa79b81d4d5db59c84d5a3bd1682 (patch) | |
| tree | 60d28afb36415883748ed778b44f9599abee801d | |
| parent | Fix length parameter to strlcpy, inputFS is a pointer. (diff) | |
| download | wireguard-openbsd-484822295e51fa79b81d4d5db59c84d5a3bd1682.tar.xz wireguard-openbsd-484822295e51fa79b81d4d5db59c84d5a3bd1682.zip | |
Move FRELE() outside fdplock in dup*(2) code. This avoids a potential
lock order issue with the file close path.
The FRELE() can trigger the close path during dup*(2) if another thread
manages to close the file descriptor simultaneously. This race is
possible because the file reference is taken before the file descriptor
table is locked for write access.
Vitaliy Makkoveev agrees
OK anton@ mpi@
| -rw-r--r-- | sys/kern/kern_descrip.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 1b79eefaf7d..744b2247801 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_descrip.c,v 1.201 2020/03/13 10:07:01 anton Exp $ */ +/* $OpenBSD: kern_descrip.c,v 1.202 2020/06/11 13:23:18 visa Exp $ */ /* $NetBSD: kern_descrip.c,v 1.42 1996/03/30 22:24:38 christos Exp $ */ /* @@ -301,13 +301,14 @@ restart: return (EBADF); fdplock(fdp); if ((error = fdalloc(p, 0, &new)) != 0) { - FRELE(fp, p); if (error == ENOSPC) { fdexpand(p); fdpunlock(fdp); + FRELE(fp, p); goto restart; } fdpunlock(fdp); + FRELE(fp, p); return (error); } /* No need for FRELE(), finishdup() uses current ref. */ @@ -373,13 +374,14 @@ restart: fdplock(fdp); if (new >= fdp->fd_nfiles) { if ((error = fdalloc(p, new, &i)) != 0) { - FRELE(fp, p); if (error == ENOSPC) { fdexpand(p); fdpunlock(fdp); + FRELE(fp, p); goto restart; } fdpunlock(fdp); + FRELE(fp, p); return (error); } if (new != i) @@ -433,13 +435,14 @@ restart: } fdplock(fdp); if ((error = fdalloc(p, newmin, &i)) != 0) { - FRELE(fp, p); if (error == ENOSPC) { fdexpand(p); fdpunlock(fdp); + FRELE(fp, p); goto restart; } fdpunlock(fdp); + FRELE(fp, p); } else { int dupflags = 0; |
