summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbeck <beck@openbsd.org>2019-11-28 16:05:25 +0000
committerbeck <beck@openbsd.org>2019-11-28 16:05:25 +0000
commit29844f7bb5bef5ffbfc45834310c6ffaf614e030 (patch)
treec2b7ebc4cb75981dc4162bb1be13dc505f290cd6
parentMerge host_v{4,6}() into host_ip(), simplify host() (diff)
downloadwireguard-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.c10
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;
}