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

O_VIA/O_RECV/O_XMIT name[IFNAMSIZ] not required NUL-terminated: kfnmatch() pattern scan runs past the 16-byte field toward/past the rule allocation

Summary

iface_match() matches interface names with kfnmatch(cmd->name, if_xname, 0) when cmd->p.glob is set. Validation only enforces the instruction length (6 words) - name[] is the trailing 16 bytes of ipfw_insn_if and is never checked for NUL termination, and the glob flag is raw user data. With all 16 name bytes non-NUL, kfnmatch walks the pattern byte-by-byte into the following instructions and, if the remainder of the rule contains no zero byte, past RULESIZE into adjacent heap (sequential OOB read until a zero). The strncmp path is properly bounded. Root-installed rule + any matching packet; only observable as a match/no-match oracle on adjacent bytes - negligible confidentiality, bounds-discipline defect. Fix: require memchr(cmd->name, 0, IFNAMSIZ) at install. [VERIFIED pass2: install-gap demonstrated live with non-NUL name rule accepted then never matching; kfnmatch rangematch walk reachable but oracle-only; fix compile-validated]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3262 Β· 9 files
FileTypeDescriptionSize
run.log β€” 724 B view raw
README.md β€” 586 B ↓ raw
VERDICT.md β€” 2.2 KB ↓ raw
build.sh β€” 162 B view raw
run.sh β€” 158 B view raw
manifest.json β€” 670 B view raw
verdict.json β€” 1.9 KB view raw
fix.diff β€” 635 B view raw
env.txt β€” 272 B view raw

DF-3262 -- verification pack

Finding: O_VIA/O_RECV/O_XMIT name[] not required NUL-terminated; kfnmatch walks past rule

Status: not_reproduced / impact leak / confidence likely

What was run

guest: addset via 2000 <16-byte-name> (same tool as DF-3261)

How to reproduce

guest: addset via 2000 vtnet0[AAAAAAAAA; ipfw -S list; traffic; ipfw show 2000

Expected

rule installs with no NUL in name[] (validation gap); never matches the control pattern

See VERDICT.md for the full narrative and verdict.json for the persisted machine verdict. Artifacts: run.log.

VERDICT.md
↓ download raw

DF-3262 verification

Kernel: DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64

Bottom line

The validation gap is demonstrated live: an O_VIA glob rule whose 16-byte name has no NUL byte installs through IP_FW_ADD (only the instruction length is checked at ip_fw2.c:5482) and shows in ipfw -S list, while a properly terminated control rule matches traffic. Rigorous source analysis of libkern fnmatch shows the out-of-bounds pattern read is genuinely reachable but oracle-only: the default, ? and leading-* branches consume pattern in lockstep with the string (bounded by if_xname, <= 15 chars + NUL), but an unterminated [ opens rangematch()s bracket scan, which walks pattern bytes until a ] or an EOS byte - past the 16-byte name, through the rest of the rule, into adjacent heap when no zero byte intervenes. The result is a match/no-match oracle on adjacent kernel heap bytes with no crash or disclosure path; classification is therefore not_reproduced for want of an observable manifestation, with the gap and the reachability analysis on record.

Kernel references

Exploit chain

(none: availability/correctness finding; no privilege chain)

Fix

require memchr(name, 0, IFNAMSIZ) at install for O_RECV/O_XMIT/O_VIA

See fix.diff in this directory (git-apply-able against the read-only sys/ tree; applied only inside the disposable verification guest).

Reproduction

build: guest: addset via 2000 <16-byte-name> (same tool as DF-3261)

run: guest: addset via 2000 vtnet0[AAAAAAAAA; ipfw -S list; traffic; ipfw show 2000

expected: rule installs with no NUL in name[] (validation gap); never matches the control pattern

Notes on the PoC (what changed vs the finding sketch)

(none)

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

not_testable
↓ fix.diffper-fix-DF-3262

Confirmed kernel references

Detail

Evidence (decisive lines)

run.log (non-NUL rule installed and listed, zero matches vs NUL-terminated control matching), VERDICT.md fnmatch branch analysis

Verified recommended fix

require memchr(name, 0, IFNAMSIZ) at install for O_RECV/O_XMIT/O_VIA

Verdict

The validation gap is demonstrated live: an O_VIA glob rule whose 16-byte name has no NUL byte installs through IP_FW_ADD (only the instruction length is checked at ip_fw2.c:5482) and shows in ipfw -S list, while a properly terminated control rule matches traffic. Rigorous source analysis of libkern fnmatch shows the out-of-bounds pattern read is genuinely reachable but oracle-only: the default, ? and leading-* branches consume pattern in lockstep with the string (bounded by if_xname, <= 15 chars + NUL), but an unterminated [ opens rangematch()s bracket scan, which walks pattern bytes until a ] or an EOS byte - past the 16-byte name, through the rest of the rule, into adjacent heap when no zero byte intervenes. The result is a match/no-match oracle on adjacent kernel heap bytes with no crash or disclosure path; classification is therefore not_reproduced for want of an observable manifestation, with the gap and the reachability analysis on record.