IPI ring/serial indices are signed int, incremented without wraparound handling (overflow after ~2^31 messages)
| Field | Value |
|---|---|
| ID | DF-0049 |
| Status | new |
| Severity | Info |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:N/I:L/A:L |
| CWE | CWE-190 Integer Overflow or Wraparound |
| File | sys/kern/lwkt_ipiq.c (gates); sys/sys/thread.h (types) |
| Lines | thread.h:218-221, lwkt_ipiq.c:232,245,466,481 |
| Area | kern |
| Confidence | speculative |
| Discovered | 2026-06-29 |
| Reported | pending |
Summary
struct lwkt_ipiq.ip_rindex/ip_xindex/ip_windex/ip_drain are int
(sys/sys/thread.h:218-221), incremented once per IPI and never reset. All
fill-level and queue-state decisions are signed subtractions of these counters
(lwkt_ipiq.c:232 level1 gate, :245 KKASSERT, :359 passive gate, :747
core loop, :1031 cpusyncq), and lwkt_wait_ipiq depends on a signed serial
comparison (:466,481). After ~2^31 (~2.1e9) IPIs on a single (src,dst) pair,
++ip_windex undergoes signed overflow (UB); on two's-complement wraparound the
differences go large-negative, so the sender's "fifo full" gates stop firing
(never waits) while the receiver's loop condition skips processing. The masked
array index (windex & MAXCPUFIFO_MASK) keeps ip_info access in-bounds, so
this is not a direct OOB write โ the realistic impact is dispatch-level
logic corruption (overwritten/unconsumed entries, repeated or skipped callbacks)
after extreme runtime on a hot CPU pair. Not directly attacker-triggerable: IPI
func/arg/rate are kernel-internal.
Root cause
sys/sys/thread.h:218-221:
int ip_rindex; /* only written by target cpu */
int ip_xindex; /* written by target, indicates completion */
int ip_windex; /* only written by source cpu */
int ip_drain; /* drain source limit */
if (ip->ip_windex - ip->ip_rindex > level1) { /* signed subtraction of monotonic counters */
Threat model & preconditions
- Impact: not attacker-reachable. Requires sustained very-high IPI rate on a
single CPU pair over long uptime (~2^31 messages โ order tens of minutes to
hours of heavy TLB-shootdown/scheduler-IPI traffic). Demonstrated impact is
the
KKASSERTpanic at:245/:1031once gating desynchronizes, or a silent stall inlwkt_wait_ipiq/lwkt_cpusync_interlock; any memory-safety escalation is speculative (depends on what the affected IPI callbacks do when double-fired or skipped). Defense-in-depth hardening. - Confidence: speculative (the signed-overflow property is real; exploit reachability is not).
Recommended fix
Make the monotonic counters unsigned int and adjust the signed serial-number
comparison in lwkt_wait_ipiq to cast explicitly:
--- a/sys/sys/thread.h
+++ b/sys/sys/thread.h
@@ -217,9 +217,9 @@
struct lwkt_ipiq {
- int ip_rindex;
- int ip_xindex;
- int ip_windex;
- int ip_drain;
+ unsigned int ip_rindex;
+ unsigned int ip_xindex;
+ unsigned int ip_windex;
+ unsigned int ip_drain;
--- a/sys/kern/lwkt_ipiq.c
+++ b/sys/kern/lwkt_ipiq.c
@@ -466
- if ((int)(ip->ip_xindex - seq) < 0) {
+ if ((int)(ip->ip_xindex - (unsigned int)seq) < 0) {
References
sys/sys/thread.h:218-221โintindices.sys/kern/lwkt_ipiq.c:232,245โ signed-subtraction fill gates.- CWE-190 Integer Overflow or Wraparound.
Timeline
- 2026-06-29 Discovered during automated file-by-file audit of
sys/kern/lwkt_ipiq.c. - pending Reported to DragonFlyBSD security contact.