From ce9eea64253d9f9be95a37cfe36e89bbb2dfa85a Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Wed, 5 Sep 2018 19:05:30 +0000 Subject: [PATCH] Correct the condition under which we allocate a terminator node. We will have last_block < blocks if the block count is divisible by BLIST_BMAP_RADIX, but a terminator node is still needed if the tree isn't balanced. In this case we were overruning the blist array by 16 bytes during initialization. While here, add a check for the invalid blocks == 0 case. PR: 231116 Reviewed by: alc, kib (previous version), Doug Moore Approved by: re (gjb) MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D17020 --- sys/kern/subr_blist.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sys/kern/subr_blist.c b/sys/kern/subr_blist.c index d77d12997a57..db7df6932633 100644 --- a/sys/kern/subr_blist.c +++ b/sys/kern/subr_blist.c @@ -224,17 +224,19 @@ blist_create(daddr_t blocks, int flags) u_daddr_t nodes, radix, skip; int digit; + if (blocks == 0) + panic("invalid block count"); + /* - * Calculate the radix and node count used for scanning. Find the last - * block that is followed by a terminator. + * Calculate the radix and node count used for scanning. */ last_block = blocks - 1; radix = BLIST_BMAP_RADIX; while (radix < blocks) { if (((last_block / radix + 1) & BLIST_META_MASK) != 0) /* - * A terminator will be added. Update last_block to the - * position just before that terminator. + * We must widen the blist to avoid partially + * filled nodes. */ last_block |= radix - 1; radix *= BLIST_META_RADIX; @@ -244,7 +246,9 @@ blist_create(daddr_t blocks, int flags) * Count the meta-nodes in the expanded tree, including the final * terminator, from the bottom level up to the root. */ - nodes = (last_block >= blocks) ? 2 : 1; + nodes = 1; + if (radix - blocks >= BLIST_BMAP_RADIX) + nodes++; last_block /= BLIST_BMAP_RADIX; while (last_block > 0) { nodes += last_block + 1;