β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-1552

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.

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.

  • DF-1551 (sibling): snread packet_length underflow heap overflow in same file.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1552 Β· 4 files
FileTypeDescriptionSize
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
VERDICT.md verdict source-confirmation analysis
↓ download 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

fixed
baseline reproduced→ patch + rebuild →patched clean

fix.diff compiled in batch kernel build rc=0 -Werror

fix.diff compiled in batch kernel build rc=0 -Werror
↓ fix.diffcombined build rc=0

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)