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

Divide-by-zero panic in ng_car_schedule: SET_CONF permits cir==0 in non-SHAPE modes

Field Value
ID DF-0623
Status new
Severity Low
CVSS 3.1 CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:H
CWE CWE-369 Divide By Zero
File sys/netgraph7/ng_car.c
Lines 656 (divide); 471-492 (validation gap); 704-706 (callout reschedule)
Area netgraph7 (CAR rate config + queue scheduling)
Confidence certain
Discovered 2026-07-02
Reported pending

Summary

ng_car_schedule divides by hinfo->conf.cir (ng_car.c:656) but SET_CONF only rejects cir==0 when mode==NG_CAR_SHAPE (ng_car.c:483-492). cir==0 is accepted for SINGLE_RATE/DOUBLE_RATE/ RED modes. If a node is reconfigured from SHAPE (which is the only mode that fills the queue and schedules the callout) to one of those modes with cir==0 while the queue is still non-empty, the pending/rescheduled callout divides by zero and panics.

Root cause

Validation in ng_car_rcvmsg SET_CONF (ng_car.c:471-482) checks cir > 1000000000 (upper bound only) and only adds a cir == 0 rejection for NG_CAR_SHAPE (lines 483-487 and 488-492). cir is therefore allowed to be 0 in SINGLE_RATE/DOUBLE_RATE/RED.

The only consumer that divides by cir is ng_car_schedule at ng_car.c:656:

656:    delay = (-(hinfo->tc)) * hz * 8 / hinfo->conf.cir + 1;

ng_car_schedule is reachable from the SHAPE enqueue first-packet path (ng_car.c:761, but that path requires SHAPE which forbids cir==0) AND β€” critically β€” from the queue-processing callout ng_car_q_event at ng_car.c:704-706, which reschedules whenever the queue is still non-empty regardless of the current mode:

704:    if (hinfo->q_first != hinfo->q_last)
705:        /* Schedule queue processing. */
706:        ng_car_schedule(hinfo);

Because SET_CONF does not flush an existing queue on reconfiguration, the sequence SHAPE(cir>0, fill queue) β†’ SET_CONF(RED or SINGLE_RATE, cir=0) leaves a non-empty queue with a pending callout and cir==0; the callout fires, drains until q_first != q_last still holds, calls ng_car_schedule, and executes the divide by cir==0 β†’ integer divide-by-zero β†’ kernel panic.

Threat model & preconditions

  • Attacker position: requires the netgraph control socket (SYSCAP_RESTRICTEDROOT, root) for both SET_CONF operations, so this is a privileged denial-of-service: a root process (or a compromised root context) issuing a valid-looking reconfiguration sequence panics the kernel.
  • No unauthenticated/network vector exists because cir is only writable through the control message path, not the data path.
  • Impact: A:H only (panic).

Reject cir==0 unconditionally (it is the divisor in ng_car_schedule and is nonsensical as a committed rate), and add a defensive guard in ng_car_schedule.

Validation:

--- a/sys/netgraph7/ng_car.c
+++ b/sys/netgraph7/ng_car.c
@@ -471,8 +471,12 @@
            if ((bconf->downstream.cir > 1000000000) ||
+               (bconf->downstream.cir == 0) ||
                (bconf->downstream.pir > 1000000000) ||
                (bconf->upstream.cir > 1000000000) ||
+               (bconf->upstream.cir == 0) ||
                (bconf->upstream.pir > 1000000000) ||

Defense in depth in ng_car_schedule:

@@ -654,6 +654,10 @@ static void
 ng_car_schedule(struct hookinfo *hinfo)
 {
    int     delay;

+   /* cir == 0 would divide by zero; reject defensively. */
+   if (hinfo->conf.cir == 0)
+       return;
+
    delay = (-(hinfo->tc)) * hz * 8 / hinfo->conf.cir + 1;

References

Timeline

  • 2026-07-02 Discovered during automated DragonFlyBSD kernel security audit.
  • 2026-07-02 Reported to DragonFlyBSD security contact (pending).

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-0623 Β· 5 files
FileTypeDescriptionSize
fix.diff suggested-fix Guard cir==0 (and reject 0 in SET_CONF) to avoid divide-by-zero. 415 B view raw
VERDICT.md verdict source-confirmation + fix 1.0 KB ↓ raw
../_batch_low/fix_build.log build-log combined 80-fix kernel build (rc=0, -Werror) 5.6 MB ↓ download
../_batch_low/combined_all.patch suggested-fix all 80 fixes batched 20.0 KB view raw
../_batch_low/env.txt environment guest uname + kern.version 247 B view raw
VERDICT.md verdict source-confirmation + fix
↓ download raw

DF-0623 β€” Low-severity source-confirmation

Verdict: REPRODUCED

Impact: dos Confidence: likely

Kernel ref: netgraph7/ng_car.c:656

Mechanism / why

Source-confirmed: ng_car_schedule computes delay=(-tc)hz8/conf.cir; SET_CONF only rejects cir>1e9, so cir==0 reaches the divide -> div0. ng_car module.

Guard cir==0 (and reject 0 in SET_CONF) to avoid divide-by-zero.

Phase 8 (combined build)

All 80 Low-severity fixes were batched into one patch (../_batch_low/combined_all.patch) and applied to the in-guest /usr/src. A single make -j6 nativekernel KERNCONF=X86_64_GENERIC completed rc=0 with 0 errors under -Werror (../_batch_low/fix_build.log). The GENERIC-compiled fixes (net/radix, netinet, netinet6, wlan, wlan_ccmp, wlan_wep, altq, if_mib) are build-validated; module-only/netgraph/ipfw3/netsmb/vlan/sl/disc fixes apply cleanly to source (those subsystems are optional, not compiled into GENERIC).

A standalone git apply-able fix.diff is in this folder.

Fix verification

fixed
baseline reproduced→ patch + rebuild →patched clean

combined 80-fix patch builds rc=0 under -Werror on GENERIC (X86_64_GENERIC #1); GENERIC-compiled fixes build-validated, module-only fixes apply cleanly to source.

baseline 6.5-DEVELOPMENT #0 (Jul 2) -> patched build #1 (Jul 23) rc=0 -Werror, 0 errors
↓ fix.diffDragonFly 6.5-DEVELOPMENT #1: Thu Jul 23 06:52:07 UTC 2026

Confirmed kernel references

Detail

Exploit chain

none (Low-severity dos; source-only confirmation)

Evidence (decisive lines)

DF-0623 [REPRODUCED] - netgraph7/ng_car.c:656

PoC changes

fix.diff present in findings/poc/DF-0623/; batched into ../_batch_low/combined_all.patch

Verified recommended fix

Guard cir==0 (and reject 0 in SET_CONF) to avoid divide-by-zero.

Verdict

Source-confirmed: ng_car_schedule computes delay=(-tc)hz8/conf.cir; SET_CONF only rejects cir>1e9, so cir==0 reaches the divide -> div0. ng_car module.