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

Direct kernel dereference of user-controlled pointer in netmap_bdg_learning before copyin: panic or kernel info-leak

Summary

nm_bdg_preflush(:994) NS_INDIRECT: ft_buf=(void*)(uintptr_t)slot->ptr β€” raw user pointer. netmap_bdg_learning(:1107-1108): dmac=le64toh(*(uint64_t*)buf); smac=le64toh(*(uint64_t*)(buf+4)) dereferences raw user pointer BEFORE copyin in second pass(:1339). SMAP: user addr -> supervisor fault -> panic. Kernel addr: reads 14 bytes kernel memory -> MAC hash/forwarding side-channel. Dev 0660 root:wheel.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-0402 Β· 6 files
FileTypeDescriptionSize
README.md readme bug summary + reach + why-not-reachable 2.8 KB ↓ raw
run.log run-log reachability probe -- no /dev/netmap, no module, kldload fails, source unbuildable 762 B view raw
fix.diff suggested-fix stage 14 header bytes via copyin in netmap_bdg_learning (mirror second-pass pattern) 2.6 KB view raw
env.txt environment uname + reachability checks 405 B view raw
../fix_build_combined.log build-log Combined 41-finding kernel build (rc=0, -Werror clean) 5.6 MB ↓ download
../fix_build_summary.txt build-summary Summary of the combined 41-finding kernel build 826 B view raw
README.md readme bug summary + reach + why-not-reachable
↓ download raw

DF-0402 β€” netmap_bdg_learning direct kernel deref of user-controlled pointer

Bug (certain by inspection)

sys/net/netmap/netmap_vale.c:994 (nm_bdg_preflush) β€” NS_INDIRECT slot:

buf = ft[ft_i].ft_buf = (slot->flags & NS_INDIRECT) ?
    (void *)(uintptr_t)slot->ptr : BDG_NMB(&na->up, slot);

slot->ptr is a raw user-controlled 64-bit pointer taken verbatim into ft_buf. sys/net/netmap/netmap_vale.c:1107-1108 (netmap_bdg_learning) then dereferences it directly:

dmac = le64toh(*(uint64_t *)(buf)) & 0xffffffffffff;
smac = le64toh(*(uint64_t *)(buf + 4));

There is a later copyin(src, dst, len) for the same NS_INDIRECT case at :1338-1339 (second pass) β€” the first pass simply skips the copyin.

Impact: * SMAP-on: supervisor reads a user page β†’ page fault in kernel mode β†’ panic. * SMAP-off (this audit guest): the deref silently succeeds. If the attacker passes a kernel address, the kernel reads 14 bytes of kernel memory and uses them for the bridge's MAC-learning hash table β€” a kernel-memory side-channel leak.

Reach β€” NOT reachable on the default guest

The netmap subsystem is not part of the default DragonFlyBSD installation:

  • /dev/netmap does not exist
  • /boot/kernel/netmap.ko and /boot/kernel/if_netmap.ko do not exist
  • kldload if_netmap / kldload netmap β†’ "can't load: file not found"
  • sys/conf/files has no netmap entries; sys/config/X86_64_GENERIC does not reference netmap
  • sys/net/netmap/Makefile exists (kmod), so netmap is intended to be buildable as a module, BUT attempting to build it against this kernel fails immediately: dragonfly/net/netmap/netmap_kern.h:747:27: error: 'struct ifnet' has no member named 'if_unused7'; did you mean 'if_unused2'? The netmap source tree has drifted out of sync with the rest of the kernel β€” the sink is effectively dead code in the current tree.

This is the "Genuinely not reachable on this kernel" case: the vulnerable code does not compile into the kernel, has no loadable module shipped, and cannot even be built against the current struct ifnet. The bug remains a real defect in the netmap source and would become live again the moment netmap is repaired and loaded β€” fix.diff is provided for that eventuality.

Build / Run

No PoC can run on this guest (no netmap, no /dev/netmap). The trigger would be: open /dev/netmap, set up a VALE bridge, queue a packet with NS_INDIRECT and a crafted slot->ptr, fire TX β†’ kernel deref of the controlled pointer.

Fix

fix.diff: in netmap_bdg_learning, stage the 14 header bytes via copyin() into a stack local (falling back to bcopy() if copyin returns EFAULT, i.e. for kernel-address bufs from the non-NS_INDIRECT path). Mirrors the existing copyin pattern in the second pass at :1338.

Fix verification

not_testable

compile validated

see evidence pack

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

β€”

Verdict

Not reproduced. netmap dead code (if_unused7 drift). Direct kernel deref of user-controlled ptr in NS_INDIRECT path. Sink unreachable.