Dead terminator guard in blst_meta_free/blst_meta_fill checks parent's bm_bighint instead of child's scan[i] β out-of-range free/fill walks uninitialized terminator slots and can index past bl_rootblks
| Field | Value |
|---|---|
| ID | DF-2789 |
| Status | new |
| Severity | Low |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:H |
| CWE | CWE-697 (latent CWE-787 / CWE-457) |
| File | sys/kern/subr_blist.c |
| Lines | 660, 775 (correct pattern :483/:519/:612/:747/:853) |
| Area | kern |
| Confidence | certain |
| Discovered | 2026-08-31 |
| Pass | 2 (GLM 5.3 second pass) |
| Bucket | memcorrupt |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
blst_meta_free and blst_meta_fill guard the child-walk loop with
if (scan->bm_bighint == (swblk_t)-1) panic(...) β but scan is the
CURRENT (parent) node, which by construction is never a terminator. All
seven other walks correctly test the CHILD slot. The intended
"freeing/filling unexpected range" panic is dead code. A free or fill
whose range extends past bl_blocks walks onto and past the terminator
slot: the terminator's union is uninitialized heap (bl_root allocated
without M_ZERO; radix_init only sets bm_bighint=-1 on terminators),
garbage is consumed as avail/bitmap state, recursion continues past
bl_rootblks, and the leaf bitmap |= / &= ~mask writes out of bounds of
the M_SWAP allocation. Latent only: every in-tree caller passes
in-range arguments β the missing guard converts a future caller bug
from a clean panic into heap corruption in the swap allocator.
Recommended fix
Test the child slot (scan[i]) exactly like every other walk β two-line diff in the row above.
Timeline
- 2026-08-31 Discovered during pass-2 audit of subr_blist.c (GLM 5.3).
No comments yet.