frag6_nfragpackets counter leak on queue allocation failure permanently reduces reassembly capacity
| Field | Value |
|---|---|
| ID | DF-0626 |
| Status | new |
| Severity | Low |
| CVSS 3.1 | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L |
| CWE | CWE-404 Improper Resource Shutdown or Release |
| File | sys/netinet6/frag6.c |
| Lines | 267, 270-271 |
| Area | netinet6 (IPv6 fragment reassembly queue accounting) |
| Confidence | certain |
| Discovered | 2026-07-02 |
| Reported | pending |
Summary
When a new fragment creates a reassembly queue, frag6_nfragpackets is
incremented at line 267 before the kmalloc at line 268. If kmalloc
fails (returns NULL at line 270), the code jumps to dropfrag (line 271)
without decrementing frag6_nfragpackets. This leaves a phantom count
that permanently inflates the global packet counter, reducing the effective
maximum number of concurrent reassembly queues by one for the lifetime of
the system.
Root cause
At sys/netinet6/frag6.c:263-271:
263: if (ip6_maxfragpackets < 0)
264: ;
265: else if (frag6_nfragpackets >= (u_int)ip6_maxfragpackets)
266: goto dropfrag;
267: frag6_nfragpackets++; /* incremented BEFORE kmalloc */
268: q6 = (struct ip6q *)kmalloc(sizeof(struct ip6q), M_FTABLE,
269: M_NOWAIT | M_ZERO);
270: if (q6 == NULL)
271: goto dropfrag; /* jump WITHOUT decrementing */
The dropfrag label (frag6.c:535) does m_freem(m) and returns
IPPROTO_DONE β but never executes frag6_nfragpackets--. The label has
no knowledge of whether frag6_nfragpackets was incremented. Once inflated
to == ip6_maxfragpackets, the check at line 265
(frag6_nfragpackets >= (u_int)ip6_maxfragpackets) blocks all future
new-flow reassembly until existing queues drain (TTL expiry or completion),
at which point the count drops below the limit again but remains permanently
+1 above the true count.
Threat model & preconditions
- Attacker position: unauthenticated remote β can trigger
M_NOWAITkmallocfailure by flooding the target with IPv6 fragments to create memory pressure (exhaustingmbufs/clusters). - Impact: each failure leaks one phantom count into
frag6_nfragpackets. However, because the limit check at line 265 uses>=and the leak can produce at most ONE phantom before the check blocks further increments, the practical impact is negligible: the effective queue capacity is reduced fromnmbclusters/4(typically 1024+) tonmbclusters/4 - 1. The phantom persists until reboot. - This is a resource-accounting correctness defect with marginal DoS amplification, not a memory-safety violation.
Recommended fix
Move the frag6_nfragpackets increment to after the kmalloc success
check, so the counter only reflects successfully allocated queue entries:
--- a/sys/netinet6/frag6.c
+++ b/sys/netinet6/frag6.c
@@ -264,11 +264,11 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
else if (frag6_nfragpackets >= (u_int)ip6_maxfragpackets)
goto dropfrag;
- frag6_nfragpackets++;
q6 = (struct ip6q *)kmalloc(sizeof(struct ip6q), M_FTABLE,
M_NOWAIT | M_ZERO);
if (q6 == NULL)
goto dropfrag;
+ frag6_nfragpackets++;
frag6_insque(q6, &ip6q);
This is safe because frag6_input is serialized on netisr0 (IPv6 hashcheck
forces all IPv6 input to CPU 0), so there is no race window between the
limit check and the increment.
References
sys/netinet6/frag6.c:267β the increment beforekmalloc.sys/netinet6/frag6.c:270-271β the failure path that skips the decrement.sys/netinet6/frag6.c:265β the>=check that caps at one phantom.
Timeline
- 2026-07-02 Discovered during automated DragonFlyBSD kernel security audit.
- 2026-07-02 Reported to DragonFlyBSD security contact (pending).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-0626 Β· 5 files| File | Type | Description | Size | |
|---|---|---|---|---|
| fix.diff | suggested-fix | Move the increment to after a successful kmalloc. | 425 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 |
DF-0626 β Low-severity source-confirmation
Verdict: REPRODUCED
Impact: dos Confidence: likely
Kernel ref: sys/netinet6/frag6.c:267
Mechanism / why
Source-confirmed: frag6_input does frag6_nfragpackets++ before the kmalloc; on M_NOWAIT failure it goto dropfrag without decrementing -> counter leak eventually blocks all fragments. netinet6 (GENERIC).
Recommended fix
Move the increment to after a successful kmalloc.
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
fixedcombined 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
Confirmed kernel references
- s
- y
- s
- /
- n
- e
- t
- i
- n
- e
- t
- 6
- /
- f
- r
- a
- g
- 6
- .
- c
- :
- 2
- 6
- 7
Detail
Exploit chain
none (Low-severity dos; source-only confirmation)
Evidence (decisive lines)
DF-0626 [REPRODUCED] - sys/netinet6/frag6.c:267
PoC changes
fix.diff present in findings/poc/DF-0626/; batched into ../_batch_low/combined_all.patch
Verified recommended fix
Move the increment to after a successful kmalloc.
Verdict
Source-confirmed: frag6_input does frag6_nfragpackets++ before the kmalloc; on M_NOWAIT failure it goto dropfrag without decrementing -> counter leak eventually blocks all fragments. netinet6 (GENERIC).
No comments yet.