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

sleepq timeout API is broken: documented sleepq_set_timeout() macro cannot compile (undefined tick_sbt/C_HARDCLOCK), sbt-vs-ticks unit confusion, and int64->int truncation into tsleep()

Field Value
ID DF-2916
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:L
CWE CWE-681 Incorrect Conversion between Numeric Types
File sys/kern/subr_sleepqueue.c
Lines :300, :331, :336 (macro: sys/sys/sleepqueue.h:117-118)
Area kern
Confidence certain
Discovered 2026-09-02
Pass 2 (GLM 5.3 second pass)
Bucket base:kern
Reported pending
Known CVE none
CVE match novel

Summary

Three independent defects in the timeout path. (1) The documented sleepq_set_timeout(wchan, timo) macro expands to sleepq_set_timeout_sbt((wchan), tick_sbt * (timo), 0, C_HARDCLOCK), but neither tick_sbt nor C_HARDCLOCK exists anywhere in the DragonFly tree (the macro is their only occurrence) β€” any user of the documented API fails to compile (proven on the guest: both undeclared errors). (2) Unit confusion: :300 stores td->td_sqtimo = sbticks + sbt where sbticks is a plain 64-bit tick counter but the FreeBSD API's sbt parameter is sbintime (1<<28 == 1 s); a FreeBSD-semantics caller asking for 500 ms gets a ~2.68-million-tick sleep (~31 days at hz=100) β€” effective hang of the calling kernel thread. (3) Truncation: the 64-bit sbintime_t timo expression is passed into tsleep()'s int timo parameter β€” implicit narrowing wraps large values to arbitrary durations. Latent (zero in-tree callers); the first compat consumer using timeouts either fails to build or hangs. Root-gated. Fix: define the macro in DragonFly terms + explicit clamp/convert before tsleep.

Timeline

  • 2026-09-02 Discovered during pass-2 audit of subr_sleepqueue.c (GLM 5.3); compiler-reproduced.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2916 Β· 13 files
FileTypeDescriptionSize
README.md β€” 666 B ↓ raw
VERDICT.md β€” 1.9 KB ↓ raw
build.log β€” 2.1 KB view raw
build.sh β€” 71 B view raw
compile_test.log β€” 1.1 KB view raw
env.txt β€” 401 B view raw
fix.diff β€” 653 B view raw
fix_run.log β€” 155 B view raw
manifest.json β€” 669 B view raw
run.sh β€” 97 B view raw
sq16.c β€” 643 B view raw
sqmacro.c β€” 644 B view raw
verdict.json β€” 2.0 KB view raw

DF-2916 PoC evidence pack

What

sleepq timeout API is broken: documented macro cannot compile; sbt/ticks unit confusion; int64->int truncation.

Build

make (KMOD sq16 against KERNBUILDDIR)

Run

make  -> fails to compile (the defect)

Expected

make fails: tick_sbt undeclared + C_HARDCLOCK undeclared (sleepqueue.h:118)

Guest: DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:04 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64 All logs are full untrimmed captures unless noted. fix.diff is the git-apply-able verified fix (authored after verification; never applied to the audit tree).

VERDICT.md
↓ download raw

DF-2916 - verification verdict

Status: reproduced | reproduced: 1 | impact: denial_of_service | confidence: certain

Defect (1) mechanically proven: a consumer module using the documented sleepq_set_timeout() macro fails to compile against the stock kernel headers with exactly the two claimed undeclared identifiers - sleepqueue.h:118 expands to tick_sbt * (timo) and C_HARDCLOCK, neither of which exists anywhere in the DFly tree (build log: error: tick_sbt undeclared ... error: C_HARDCLOCK undeclared, both at sleepqueue.h:118). Defects (2)/(3) are arithmetically demonstrated from the code: :300 stores td->td_sqtimo = sbticks + sbt where sbticks is a plain 64-bit tick counter, so a FreeBSD-semantics 500ms sbt (0x08000000) becomes ~1.34M ticks (~15.5 days at hz=100), and the int64 timo narrows into tsleep int parameter at :331/:336. Zero in-tree callers (latent API); fix (macro in DFly terms) A/B validated: the consumer module COMPILES against the patched header.

Evidence pointers

sq16_build.log: two undeclared-identifier errors at sleepqueue.h:118

Kernel references

PoC changes vs the filing sketch

none

Fix

recommendation: define the macro in DFly terms (ticks) + clamp on the tsleep boundary

fix status: fixed

A/B: consumer module compiles against patched header in fix-all kernel build

Guest: DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:04 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64

Fix status (batch validation)

Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.

Fix verification

fixed
baseline reproduced→ patch + rebuild →patched clean

A/B: consumer module compiles against the patched header (SQ16-OK on fix kernel vs FAIL on stock).

↓ fix.diffper-fix-DF-2916

Confirmed kernel references

Detail

Evidence (decisive lines)

sq16_build.log: two undeclared-identifier errors at sleepqueue.h:118

PoC changes

none

Verified recommended fix

define the macro in DFly terms (ticks) + clamp on the tsleep boundary

Verdict

Defect (1) mechanically proven: a consumer module using the documented sleepq_set_timeout() macro fails to compile against the stock kernel headers with exactly the two claimed undeclared identifiers - sleepqueue.h:118 expands to tick_sbt * (timo) and C_HARDCLOCK, neither of which exists anywhere in the DFly tree (build log: error: tick_sbt undeclared ... error: C_HARDCLOCK undeclared, both at sleepqueue.h:118). Defects (2)/(3) are arithmetically demonstrated from the code: :300 stores td->td_sqtimo = sbticks + sbt where sbticks is a plain 64-bit tick counter, so a FreeBSD-semantics 500ms sbt (0x08000000) becomes ~1.34M ticks (~15.5 days at hz=100), and the int64 timo narrows into tsleep int parameter at :331/:336. Zero in-tree callers (latent API); fix (macro in DFly terms) A/B validated: the consumer module COMPILES against the patched header.