rman_reserve_resource window arithmetic wraps when count-1 > end: allocation escapes the caller's [start,end] window (and can produce an inverted r_end < r_start node when start+count-1 overflows)
| Field | Value |
|---|---|
| ID | DF-2855 |
| Status | new |
| Severity | Low |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:L |
| CWE | CWE-190 Integer Overflow or Wraparound |
| File | sys/kern/subr_rman.c |
| Lines | 224, 238, 250, 279 |
| Area | kern |
| Confidence | likely |
| Discovered | 2026-09-02 |
| Pass | 2 (GLM 5.3 second pass) |
| Bucket | memcorrupt |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
Sibling of DF-0090 (count==0) with a different input class: when
count−1 > end, the scan-break s->r_start > end − (count−1) wraps and
never fires, and ulmax(start + count − 1, end) lets rend exceed the
caller's end, so rv->r_end = rstart + count − 1 is granted BEYOND the
requested window (violating the documented contract — e.g. a PCI bridge
window can be exceeded, mapping MMIO outside the programmed window). If
start+count−1 additionally wraps ULONG_MAX, an inverted r_end < r_start
node results. Driver-bug/firmware-gated (no in-tree caller passes
count>end+1). Distinct from DF-2853 (no alignment involved).
Recommended fix
Validate the request window once at entry (subsumes DF-0090):
if (count == 0 || end < start || start + count - 1 < start ||
end - (count - 1) > end) return (NULL); — row diff above.
Timeline
- 2026-09-02 Discovered during pass-2 audit of subr_rman.c (GLM 5.3).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2855 · 3 files| File | Type | Description | Size | |
|---|---|---|---|---|
| v26harness.c | — | 14.3 KB | view raw | |
| run.log | — | 294 B | view raw | |
| fix.diff | — | 680 B | view raw |
Fix verification
fixedPatched kernel: both malformed reservations are now rejected at entry - req window [0x0,0x100] count=0x2000 -> denied and the overflow case -> denied (baseline: granted with r_end beyond the window and an inverted node).
cmd=1 on patched kernel: both requests denied
Confirmed kernel references
Detail
Exploit chain
rman_reserve_resource(count-1 > end) -> :238 wrap skips break -> :250 ulmax lets rend exceed window -> granted r_end beyond caller end / inverted node
Evidence (decisive lines)
v26harness.c t1 (cmd=1); df2855_mod.log: window escape 0x1FFF vs 0x100 + INVERTED node granted
PoC changes
first attempt panicked in rman_init (rm_type must be RMAN_ARRAY; the panic itself documents that rman_init has an assert path)
Verified recommended fix
--- sys/kern/subr_rman.c 2026-06-29 12:51:19.000000000 +0000
Verdict
Reproduced with a kernel harness calling rman_reserve_resource directly (sys/kern/subr_rman.c:204+). Case A: request window [0x0,0x100] with count=0x2000 (count-1 > end) - the scan-break test s->r_start > end - (count - 1) at :238 wraps and never fires, and the grant was issued with r_start=0 r_end=0x1FFF: the allocation EXCEEDS the callers window end 0x100 by 0x1EFF bytes (a PCI bridge window can be silently exceeded). Case B: start=0xFFFFFFFFFFFF0000 count=0x20000 - start+count-1 wraps, producing an INVERTED resource node with r_end=0xFFFF < r_start=0xFFFFFFFFFFFF0000, corrupting the sorted resource list. No panic; clean, deterministic grant of out-of-window and inverted allocations. No in-tree caller passes count > end+1 (driver-bug/firmware-gated as the finding states); the entry-validation fix (reject count==0, start>end, or count-1 > end-start) is compile-validated and A/B-verified (patched kernel returns NULL for both cases).
No comments yet.