⬢ DragonFlyBSD Kernel Audit
DF-2790 / fix.diff
← back to finding ↓ download raw
--- a/sys/kern/subr_blist.c	2026-06-29 12:51:19.000000000 +0000
+++ b/sys/kern/subr_blist.c	2026-10-26 00:25:42.773043131 +0000
@@ -183,6 +183,13 @@
 	 * Radix can exceed BLIST_BMAP_RADIX bits even if swblk_t is limited
 	 * to BLIST_BMAP_RADIX bits.
 	 */
+	/*
+	 * Domain validation: the radix math only supports the documented
+	 * range [1, BLIST_MAXBLKS]; larger values overflow the int64 radix
+	 * calculation and can spin forever.
+	 */
+	KKASSERT(blocks >= 1 && blocks <= BLIST_MAXBLKS);
+
 	radix = BLIST_BMAP_RADIX;
 
 	while (radix < blocks) {
@@ -231,11 +238,13 @@
  *		     not be allocated.
  */
 
-swblk_t 
+swblk_t
 blist_alloc(blist_t bl, swblk_t count)
 {
 	swblk_t blk = SWAPBLK_NONE;
 
+	if (bl && count < 1)
+		return(SWAPBLK_NONE);
 	if (bl) {
 		if (bl->bl_radix == BLIST_BMAP_RADIX)
 			blk = blst_leaf_alloc(bl->bl_root, 0, 0, count);
@@ -253,6 +262,8 @@
 {
 	swblk_t blk = SWAPBLK_NONE;
 
+	if (bl && count < 1)
+		return(SWAPBLK_NONE);
 	if (bl) {
 		if (bl->bl_radix == BLIST_BMAP_RADIX)
 			blk = blst_leaf_alloc(bl->bl_root, blkat, 0, count);
@@ -271,9 +282,11 @@
  *			found.
  */
 
-void 
+void
 blist_free(blist_t bl, swblk_t blkno, swblk_t count)
 {
+	if (bl && count < 1)
+		return;
 	if (bl) {
 		if (bl->bl_radix == BLIST_BMAP_RADIX)
 			blst_leaf_free(bl->bl_root, blkno, count);
@@ -295,6 +308,8 @@
 {
 	swblk_t filled;
 
+	if (bl && count < 1)
+		return 0;
 	if (bl) {
 		if (bl->bl_radix == BLIST_BMAP_RADIX) {
 			filled = blst_leaf_fill(bl->bl_root, blkno, count);