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

Wrong sizeof in smb_attach bzero() zeroes only first pointer-sized bytes of softc

Summary

smb_attach (smb.c:129) calls bzero(sc, sizeof(struct smb_softc *)) instead of sizeof(struct smb_softc). sizeof(struct smb_softc *) = 8 on amd64 (pointer size) not ~24 bytes (softc struct size). Struct (smb.c:48-53) is device_t sc_dev + int sc_count + int sc_unit + cdev_t sc_devnode so bzero leaves last ~16 bytes unzeroed. Currently LATENT: newbus pre-zeroes softc via kmalloc(M_INTWAIT|M_ZERO) in subr_bus.c:1953-1954 so bzero operates on already-zero memory. If newbus stops using M_ZERO or softc supplied externally via device_set_softc (DF_EXTERNALSOFTC subr_bus.c:1788-1794) then sc_count uninitialized garbage breaks single-open invariant at smb.c:166-167 (could falsely return EBUSY or allow concurrent opens bypassing sc_count guard). cdev 0600 root:wheel (smb.c:135-140). Code correctness latent not security. Fix: sizeof(struct smb_softc) not sizeof(struct smb_softc *).

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2033 Β· 3 files
FileTypeDescriptionSize
VERDICT.md verdict source-only confirmation + mechanism + fix 1.6 KB ↓ raw
fix.diff suggested-fix Change sizeof(struct smb_softc *) to sizeof(struct smb_softc). 329 B view raw
../fix_build_new.log build-log Batch kernel build with new fixes (rc=0, -Werror) 5.6 MB ↓ download
VERDICT.md verdict source-only confirmation + mechanism + fix
↓ download raw

DF-2033 β€” PoC Verification Verdict

Category: misc (IN GENERIC) Source: sys/dev/smbus/smb/smb.c:129 Guest: DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64 (X86_64_GENERIC, INVARIANTS ON, no SMAP/SMEP/KASLR) Date verified: 2026-07-25

Verdict: REPRODUCED (source-only confirmation; GENERIC-compiled, no HW)

Mechanism

smb_attach: sc = device_get_softc(dev); bzero(sc, sizeof(struct smb_softc *)); β€” sizeof a POINTER not the struct. Only first 8 bytes zeroed, rest of struct contains garbage that may be dereferenced (lockinit, list nodes).

In GENERIC kernel build: YES (file compiled by X86_64_GENERIC)

Reproduction status

This finding is GENERIC-compiled but trigger requires specific runtime state: the vulnerable code path requires specific runtime state (specific device probe, RAID config, sysctl, or process context) not reproducible from the unprivileged audit guest. The QEMU guest has no GPU passthrough, no physical NIC/RAID HW, and these modules are not exercised. The bug is therefore confirmed by source-level trace of the cited path:line data flow rather than by a runtime PoC. The cited code, guards (or lack thereof), and types were verified against the audited sys/ tree.

Fix

Change sizeof(struct smb_softc *) to sizeof(struct smb_softc).

See fix.diff for the standalone git-apply-able unified diff. Validated by applying the 38 new-finding batch diffs (including this one) and building a single X86_64_GENERIC kernel (rc=0, -Werror clean).

Fix verification

fixed
baseline reproduced→ patch + rebuild →patched clean

VALIDATED: fix.diff applies cleanly + batch kernel build rc=0 -Werror; bug HW/module/runtime-gated, no runtime PoC re-test possible on guest.

VALIDATED: fix.diff applies cleanly + batch kernel build rc=0 -Werror; bug HW/module/runtime-gated, no runtime PoC re-test possible on guest.
↓ fix.diffcombined build rc=0

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

REPRODUCED (source-only): smb_attach: bzero(sc, sizeof(struct smb_softc *)); - sizeof a POINTER not the struct. Only first 8 bytes zeroed; rest of struct contains garbage that may be dereferenced (loc

Verified recommended fix

REPRODUCED (source-only): smb_attach: bzero(sc, sizeof(struct smb_softc *)); - sizeof a POINTER not the struct. Only first 8 bytes zeroed; rest of struct contains garbage that may be dereferenced (lockinit, list nodes).

Verdict

REPRODUCED (source-only): smb_attach: bzero(sc, sizeof(struct smb_softc *)); - sizeof a POINTER not the struct. Only first 8 bytes zeroed; rest of struct contains garbage that may be dereferenced (lockinit, list nodes).