diff options
author | 2019-11-28 16:05:25 +0000 | |
---|---|---|
committer | 2019-11-28 16:05:25 +0000 | |
commit | 29844f7bb5bef5ffbfc45834310c6ffaf614e030 (patch) | |
tree | c2b7ebc4cb75981dc4162bb1be13dc505f290cd6 | |
parent | Merge host_v{4,6}() into host_ip(), simplify host() (diff) | |
download | wireguard-openbsd-29844f7bb5bef5ffbfc45834310c6ffaf614e030.tar.xz wireguard-openbsd-29844f7bb5bef5ffbfc45834310c6ffaf614e030.zip |
Fix panic noticed by bluhm@ and florian@. bp->b_pobj is used
to determine if the buffer has pages to free. we have to
set this pointer only after we could sleep allocating pages.
setting it before creates the potential for a race to free
us while we are sleeping
ok kettenis@
-rw-r--r-- | sys/kern/vfs_biomem.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/sys/kern/vfs_biomem.c b/sys/kern/vfs_biomem.c index 55eb6f5af7e..2be52c300f3 100644 --- a/sys/kern/vfs_biomem.c +++ b/sys/kern/vfs_biomem.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_biomem.c,v 1.42 2019/11/28 02:30:38 beck Exp $ */ +/* $OpenBSD: vfs_biomem.c,v 1.43 2019/11/28 16:05:25 beck Exp $ */ /* * Copyright (c) 2007 Artur Grabowski <art@openbsd.org> @@ -258,8 +258,7 @@ buf_alloc_pages(struct buf *bp, vsize_t size) KASSERT(bp->b_data == NULL); splassert(IPL_BIO); - bp->b_pobj = &bp->b_uobj; - uvm_objinit(bp->b_pobj, NULL, 1); + uvm_objinit(&bp->b_uobj, NULL, 1); /* * Attempt to allocate with NOWAIT. if we can't, then throw @@ -268,13 +267,13 @@ buf_alloc_pages(struct buf *bp, vsize_t size) * memory for us. */ do { - i = uvm_pagealloc_multi(bp->b_pobj, 0, size, + i = uvm_pagealloc_multi(&bp->b_uobj, 0, size, UVM_PLA_NOWAIT | UVM_PLA_NOWAKE); if (i == 0) break; } while (bufbackoff(&dma_constraint, size) == 0); if (i != 0) - i = uvm_pagealloc_multi(bp->b_pobj, 0, size, + i = uvm_pagealloc_multi(&bp->b_uobj, 0, size, UVM_PLA_WAITOK); /* should not happen */ if (i != 0) @@ -284,6 +283,7 @@ buf_alloc_pages(struct buf *bp, vsize_t size) bcstats.numbufpages += atop(size); bcstats.dmapages += atop(size); SET(bp->b_flags, B_DMA); + bp->b_pobj = &bp->b_uobj; bp->b_poffs = 0; bp->b_bufsize = size; } |