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

config_red divides by (max_th-min_th) and max_th without zero check: kernel panic β€” same bug class as dummynet v1 unfixed

Summary

config_red(:1351-1356): x->c_1=ioc_fs->max_p/(ioc_fs->max_th-ioc_fs->min_th). max_th==min_th -> div0 panic. GENTLE_RED: x->c_3=(SCALE(1)-max_p)/max_th; max_th==0 -> div0. set_fs_parms ignores return (:1452 "XXX should check errors"). Same unfixed bug as DF-0374 (v1). Single setsockopt triggers panic. Root in jail can panic host kernel.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-0382 Β· 12 files
FileTypeDescriptionSize
df_0382_div0.c trigger-source setsockopt(IPPROTO_IP, IP_DUMMYNET_CONFIGURE) with RED max_th==min_th or max_th==0 2.7 KB view raw
build.sh build-script cc -O2 -Wall -o df_0382_div0 df_0382_div0.c 106 B view raw
run.sh run-script loads dummynet3, runs trigger as root 791 B view raw
README.md readme bug summary + reach + build/run/expected 1.6 KB ↓ raw
panic.txt panic-signature Fatal trap 18 div fault at set_fs_parms+0x8e 578 B view raw
run.log run-log baseline panic evidence (ssh_rc=124, guest down) 984 B view raw
fix.diff suggested-fix validate max_th>min_th and max_th>0 in config_red; propagate via set_fs_parms 1.9 KB view raw
fix_build.log build-log single-fix nativekernel build, full output, rc=0 5.6 MB ↓ download
fix_run.log run-log patched-kernel run: EINVAL, no panic 385 B view raw
env.txt environment uname + cc version 247 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 + build/run/expected
↓ download raw

DF-0382 β€” config_red divide-by-zero panic

Bug

sys/net/dummynet3/ip_dummynet3.c:1351 and :1354:

x->c_1 = ioc_fs->max_p / (ioc_fs->max_th - ioc_fs->min_th);   /* div0 if max_th==min_th */
...
if (x->flags_fs & DN_IS_GENTLE_RED) {
    x->c_3 = (SCALE(1) - ioc_fs->max_p) / ioc_fs->max_th;      /* div0 if max_th==0 */

set_fs_parms (:1452) calls config_red and ignores its return ("XXX should check errors"), so neither denominator is validated before the divides.

Reach

setsockopt(s, IPPROTO_IP, IP_DUMMYNET_CONFIGURE /*60*/, &ioc_pipe, sizeof ioc_pipe) on a raw IP socket (socket(AF_INET, SOCK_RAW, IPPROTO_RAW)). Handled by rip_ctloutput β†’ ip_dn_sockopt β†’ config_pipe β†’ set_fs_parms β†’ config_red. The raw IP socket requires SYSCAP_NONET_RAW (sys/netinet/raw_ip.c:rip_attach), i.e. root or jail-root (the finding's stated threat: jail-root can panic the host kernel).

Build

cc -O2 -o df_0382_div0 df_0382_div0.c

Run (as root β€” needs raw socket capability)

./df_0382_div0            # default: max_th==min_th path (line 1351)
./df_0382_div0 gentle     # GENTLE_RED path, max_th==0 (line 1354)

Expected (bug present)

Kernel divide-by-zero panic β€” pid 0 (setsockopt) trap 9: divide error. Guest dies, ssh drops, dfbsd-qemu/boot.log shows the panic.

Preconditions

  • kldload dummynet3 (or build-time). On this guest the module is not auto-loaded; ip_dn_sockopt returns ENOENT/ENOEXEC until it is loaded, so the trigger script loads it as root before issuing the option.
  • Root-equivalent credential (raw socket capability).

Fix verification

fixed

validated

see evidence pack
↓ fix.diffDragonFly 6.5-DEVELOPMENT #1: Sat Jul 18 06:27:30 UTC 2026

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

β€”

Verdict

REPRODUCED (live panic). config_red div-by-zero max_th==min_th or max_th==0. Root-only (SYSCAP_NONET_RAW). dummynet3 KLD.