chip_ids[15] indexed by (rev>>4)&0xF is a 1-element OOB read at probe/attach when chip reports rev with high nibble 0xF
- File:
sys/dev/netif/sn/if_sn.c - Lines: 140, 175, 176, 1303
- Severity: Low
- CVSS:
CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U:C:N/I:N/A:L - CWE: CWE-125 Out-of-bounds Read
- Confidence: likely
Summary
The driver declares static const char *chip_ids[15] (indices 0..14) but indexes
it with chip_ids[(rev >> 4) & 0xF], whose mask yields 0..15.
When the SMC91C92 REVISION_REG_W returns a value with bits 4..7 = 0xF (a value
no real SMC chip produces, but trivially returned by a malicious PCMCIA card or
PCI passthrough), index 15 reads one pointer past the array in .rodata; in
sn_attach (if_sn.c:175-176) the result is dereferenced as a string by
kprintf if non-NULL, panicking or printing garbage.
Root cause
if_sn.c:140 static const char *chip_ids[15] β array of 15 const char *
pointers, valid indices 0..14.
if_sn.c:175-176:
if (chip_ids[(rev >> 4) & 0xF])
kprintf("%s ", chip_ids[(rev >> 4) & 0xF]);
and if_sn.c:1303:
if (!chip_ids[(revision_register >> 4) & 0xF])
β the mask & 0xF admits index 15, which is past the end of the 15-element
array.
REVISION_REG_W (if_snreg.h:331) is a 16-bit chip register; the upper nibble
holds the chip id (3, 4, 5, 7, 8 for known SMC parts).
No real chip returns 0xF, but a malicious PCMCIA card or QEMU-emulated function
can return e.g. 0xFFFF, giving index 15.
Threat
Attacker has a malicious PCMCIA / PCI-passed-through NIC that returns
rev=0xFFFF (or any value with bits 4..7 = 0xF) from REVISION_REG_W during
autoconf / kldload of if_sn.
In sn_probe (if_sn.c:1303) the OOB read may return NULL (probe rejects
device, safe) or non-NULL (probe accepts device, then sn_attach's kprintf at
if_sn.c:176 dereferences a possibly-invalid pointer β panic).
Local, requires physical or passthrough access to a malicious NIC; impact is local DoS at attach time.
No privilege escalation, no info leak beyond a possible garbage kprintf line.
Exploit / PoC
Reproduce with a QEMU-emulated SMC91C92 that returns 0xFFFF from
REVISION_REG_W, or with a kld module that hooks sn_probe to overwrite the
inw() result.
Boot the host with the device present / kldload if_sn β
Fatal trap 12: page fault while in kernel mode inside kprintf(%s) at
if_sn.c:176 (if the OOB word is non-NULL) OR sn0: <unknown> style acceptance
if NULL.
Capture dmesg.txt with the panic.
No escalation path; pure attach-time DoS.
Recommended fix
Size the table to match the mask (16) and reject unknown rev ids explicitly, OR bound the index. Simplest: change the array size.
--- a/sys/dev/netif/sn/if_sn.c
+++ b/sys/dev/netif/sn/if_sn.c
@@ -140,3 +140,3 @@
-static const char *chip_ids[15] = {
+static const char *chip_ids[16] = {
NULL, NULL, NULL,
@@ -148,3 +148,3 @@
NULL, NULL, NULL,
- NULL, NULL, NULL
+ NULL, NULL, NULL,
+ NULL /* 15: unknown / future */
};
Now & 0xF is always in-bounds; the trailing NULL causes sn_probe to reject
unknown rev ids and sn_attach to skip the kprintf, which is the correct
behavior for an unrecognized chip.
Related findings
- DF-1551 (sibling):
snreadpacket_lengthunderflow heap overflow in same file.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1552 Β· 4 files| File | Type | Description | Size | |
|---|---|---|---|---|
| fix.diff | suggested-fix | git-apply-able fix for the cited bug | 492 B | view raw |
| VERDICT.md | verdict | source-confirmation analysis | 1.0 KB | β raw |
| build.sh | build-script | N/A (source-only) | 65 B | view raw |
| run.sh | run-script | N/A (source-only) | 89 B | view raw |
DF-1552 VERDICT
Verdict: REPRODUCED (source-confirmed)
Impact: Low (driver-level NULL deref / OOB / leak / DoS β hardware-gated)
Mechanism: if_sn.c:140 static const char *chip_ids[15] (indices 0..14). 175-176 kprintf(%s, chip_ids[(rev>>4)&0xF]); 1303 sn_probe if (!chip_ids[(revision_register>>4)&0xF]). & 0xF yields 0..15 so index 15 reads
Citation: sys/dev/netif/sn/if_sn.c:140-176
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 status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
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: chip_ids[15] indexed by (rev>>4)&0xF yields 0-15 OOB (if_sn.c:140,175)
Verified recommended fix
Source-confirmed: chip_ids[15] indexed by (rev>>4)&0xF yields 0-15 OOB (if_sn.c:140,175)
Verdict
Source-confirmed: chip_ids[15] indexed by (rev>>4)&0xF yields 0-15 OOB (if_sn.c:140,175)
No comments yet.