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 | 704 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-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 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.