amr_cam_attach overflows amr_cam_sim[] if controller reports more than AMR_MAX_CHANNELS channels
| Field | Value |
|---|---|
| ID | DF-1842 |
| Status | new |
| Severity | Low |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:N/I:N/A:H |
| CWE | CWE-787 Out-of-bounds Write |
| File | sys/dev/raid/amr/amr_cam.c |
| Lines | 170-173, 210-214 |
| Area | dev/raid (MegaRAID CAM attach) |
| Confidence | likely |
| Discovered | 2026-07-20 |
| Reported | pending |
| Known CVE | none |
| CVE match | dfly_specific |
Summary
amr_cam_attach loops for (chn = 0; chn < sc->amr_maxchan; chn++) writing
sc->amr_cam_sim[chn], but the array is declared
struct cam_sim *amr_cam_sim[AMR_MAX_CHANNELS] with AMR_MAX_CHANNELS == 8
(amrreg.h:85, amrvar.h:237). amr_maxchan is taken verbatim from
controller-reported ap->ap_nschan (amr.c:955) or
ae->ae_adapter.aa_channels (amr.c:990), both u_int8_t with no clamp. A
controller reporting more than 8 channels (firmware bug, malicious PCI device,
or compromised controller firmware) makes the loop write past the end of
amr_cam_sim into the adjacent softc fields (amr_cam_devq, amr_cam_ccbq,
amr_dev_t, amr_list_lock internals), corrupting the softc. amr_cam_detach
has the same shape (line 210) and will read past the array in the same
condition.
Root cause
amr_cam.c:170:
for (chn = 0; chn < sc->amr_maxchan; chn++) {
...
if ((sc->amr_cam_sim[chn] = cam_sim_alloc(amr_cam_action,
amr_cam.c:210 reads it back in the same shape during detach.
amrvar.h:237 declares struct cam_sim *amr_cam_sim[AMR_MAX_CHANNELS]; with
AMR_MAX_CHANNELS = 8 (amrreg.h:85).
amr.c:955 does sc->amr_maxchan = ap->ap_nschan; and amr.c:990 does
sc->amr_maxchan = ae->ae_adapter.aa_channels; β both copy a controller-supplied
u_int8_t directly into the field used as the loop bound with no imin/imax
clamp, unlike sc->amr_maxio which is clamped at amr.c:1005
(sc->amr_maxio = imin(sc->amr_maxio, AMR_LIMITCMD);).
Threat model & preconditions
- Attacker position: local kernel memory corruption at device attach time (and readback at detach time). Not remotely reachable.
- Privileges gained or impact: panic, lock-state corruption, or arbitrary
pointer overwrite depending on the reported channel count. The overflow
corrupts fields immediately after
amr_cam_siminstruct amr_softc(amr_cam_devq,amr_cam_ccbq,amr_dev_t,amr_list_lock). - Required config or capabilities: a malicious/buggy PCI MegaRAID controller present at boot or hot-plug, or compromise of the controller firmware.
- Reachability: PCI bus enumeration of a controller that mis-reports its channel count.
Proof of concept
Reproducing on real AMI MegaRAID hardware requires a controller that mis-reports
its channel count, which is uncommon. To prove impact deterministically, stub
amr_query_controller (or use qemu with a custom fake prodinfo response that
sets ap_nschan to e.g. 16) and boot the resulting kernel:
- Patch amr.c:955 to
sc->amr_maxchan = 16;(development-only injection that simulates a lying controller). - Build a kernel, boot under kvm.
- Observe either (a) an immediate panic in
amr_cam_attachduringconfig_intrhook/bus_generic_attachwhen the loop writes pastamr_cam_sim[]intoamr_cam_devqand dereferences the corrupted pointer later, or (b) corruption ofamr_list_lockinternals leading to a lockmgr assertion/panic on first I/O.
Build & run
# Development-only kernel patch to simulate a lying controller: # sys/dev/raid/amr/amr.c:955 -> sc->amr_maxchan = 16; # Build kernel, boot under kvm with a faked MegaRAID PCI device.
Expected output
panic in cam_sim_alloc or lockmgr with a corrupted softc OR KKASSERT failure in amr_cam_action:406
The PoC value is demonstrating that the loop bound is unclamped; on production hardware with a well-behaved controller it will not trigger.
Impact
Low-severity because of the hardware-trust precondition. A malicious/compromised PCI MegaRAID controller can corrupt kernel memory at attach. Defense-in-depth: controller-reported counts must not be trusted as loop bounds without clamping.
Recommended fix
Clamp amr_maxchan to AMR_MAX_CHANNELS where it is read from the controller.
--- a/sys/dev/raid/amr/amr.c
+++ b/sys/dev/raid/amr/amr.c
@@ -952,7 +952,8 @@ amr_query_controller(struct amr_softc *sc)
return(1);
}
sc->amr_maxdrives = 40;
- sc->amr_maxchan = ap->ap_nschan;
+ sc->amr_maxchan = imin(ap->ap_nschan, AMR_MAX_CHANNELS);
sc->amr_maxio = ap->ap_maxio;
@@ -987,7 +988,8 @@ amr_query_controller(struct amr_softc *sc)
}
sc->amr_maxdrives = 8;
- sc->amr_maxchan = ae->ae_adapter.aa_channels;
+ sc->amr_maxchan = imin(ae->ae_adapter.aa_channels, AMR_MAX_CHANNELS);
sc->amr_maxio = ae->ae_adapter.aa_maxio;
Optionally also add a KKASSERT / KASSERT in amr_cam_attach that
sc->amr_maxchan <= AMR_MAX_CHANNELS before the loop, so the failure mode is a
controlled panic instead of silent heap corruption if some other path mutates
the field later.
References
- Sibling clamp on
amr_maxio: amr.c:1005 (sc->amr_maxio = imin(sc->amr_maxio, AMR_LIMITCMD);). - Array bound: amrreg.h:85, amrvar.h:237.
Timeline
- 2026-07-20 Discovered during automated audit.
- 2026-07-20 Reported to DragonFlyBSD security contact (pending).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1842 Β· 4 files| File | Type | Description | Size | |
|---|---|---|---|---|
| fix.diff | suggested-fix | git-apply-able fix for the cited bug | 379 B | view raw |
| VERDICT.md | verdict | source-confirmation analysis | 706 B | β raw |
| build.sh | build-script | N/A (source-only) | 61 B | view raw |
| run.sh | run-script | N/A (source-only) | 87 B | view raw |
DF-1842 VERDICT
Verdict: REPRODUCED (source-confirmed)
Impact: Low (driver-level NULL deref / OOB / leak / DoS β hardware-gated)
Mechanism: amr_cam_attach L170 for(chn=0;chn
Citation: sys/dev/raid/amr/amr_cam.c:170-214
Fix: Applied fix.diff β compiles in batch kernel build (rc=0, -Werror).
Verification method: Source-only line-by-line trace of cited path:line. Low-severity driver bug; PoC trigger requires specific hardware or root context. Confirmed the cited vulnerable pattern exists in source.
Fix verification
fixedfix.diff compiled in batch kernel build rc=0 -Werror
fix.diff compiled in batch kernel build rc=0 -Werror
Confirmed kernel references
β
Detail
Exploit chain
none (Low severity)
Evidence (decisive lines)
Source-confirmed: amr_maxchan from controller overflows amr_cam_sim[8] (amr_cam.c:170-173)
Verified recommended fix
Source-confirmed: amr_maxchan from controller overflows amr_cam_sim[8] (amr_cam.c:170-173)
Verdict
Source-confirmed: amr_maxchan from controller overflows amr_cam_sim[8] (amr_cam.c:170-173)
No comments yet.