journal_wthread pad-skip accounting bug: total_acked += bytes counts all pending bytes instead of the pad size, inflating bytessent (MOUNTCTL_STATUS)
| Field | Value |
|---|---|
| ID | DF-2749 |
| Status | new |
| Severity | Info |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:N/I:L/A:N |
| CWE | CWE-682 Incorrect Calculation |
| File | sys/kern/vfs_journal.c |
| Lines | 220-221 |
| Area | kern |
| Confidence | certain |
| Discovered | 2026-08-30 |
| Pass | 2 (GLM 5.3 second pass) |
| Bucket | base:kern |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
When the worker skips a pad record it advances rindex by the aligned
pad size but does jo->total_acked += bytes where bytes = windex -
rindex (everything still pending), double-counting and pre-counting
unwritten data; bytessent (mountctl status) becomes garbage under pad
churn, breaking consumer-side reconciliation of the mirror stream. Fix
included and validated in the DF-2747 patched-kernel build.
Recommended fix
--- a/sys/kern/vfs_journal.c
+++ b/sys/kern/vfs_journal.c
@@ -220,7 +220,7 @@
jo->fifo.rindex += (rawp->recsize + 15) & ~15;
- jo->total_acked += bytes;
+ jo->total_acked += (rawp->recsize + 15) & ~15; /* DF-2749 */
Timeline
- 2026-08-30 Discovered during pass-2 audit of vfs_journal.c (GLM 5.3).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2749 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | β | 1.5 KB | β raw | |
| README.md | β | 229 B | β raw | |
| build.sh | β | 85 B | view raw | |
| run.sh | β | 49 B | view raw | |
| env.txt | β | 314 B | view raw | |
| manifest.json | β | 597 B | view raw | |
| verdict.json | β | 2.0 KB | view raw | |
| fix.diff | β | 519 B | view raw |
DF-2749 evidence pack
- finding: sys/kern/vfs_journal.c (218-222)
- verdict: reproduced (certain) - see VERDICT.md
- source-only confirmation (no runtime PoC)
- reproduce: build.sh / run.sh
- fix.diff: present, git-apply-able
DF-2749 - Verification Verdict
Status: reproduced Impact: none (hardening) Confidence: certain
Mechanism
journal_wthread pad-skip branch advances fifo.rindex by the padded record size but increments total_acked by bytes - the WHOLE pending amount - so every pad record inflates the acked-byte accounting reported through MOUNTCTL_STATUS; the non-fullduplex sub-branch already adds the pad size again (double count on that path).
Verdict
source-confirmed (no runtime PoC; deterministic code trace of the cited path:line in the read-only sys/ tree). Code-certain accounting bug (bytessent/journal stats only); no runtime rig (mounting a journal requires the mountctl setup outside this Info batch budget). fix.diff counts the pad size once and stops the inner double-add.
Threat / reachability
Journal status/ack accounting wrongness (bytessent inflated); no memory-safety impact.
Privilege escalation assessment
n/a (hardening)
Fix
total_acked += (rawp->recsize + 15) & ~15 once; drop the inner increment (keep the xindex advance).
Kernel references
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
not_testablefix.diff compile-validated in the batch combined kernel build (all 37 diffs of this batch applied to in-guest /usr/src; make -j6 nativekernel KERNCONF=X86_64_GENERIC, see batch build log referenced in VERDICT.md); no behavior A/B performed for this Info-tier item; behavior A/B intentionally skipped for Info tier
batch combined kernel build log (see findings/poc/_batch41 note in VERDICT.md)
Confirmed kernel references
Detail
Exploit chain
no escalation path (Info-tier hardening; see VERDICT.md)
Evidence (decisive lines)
VERDICT.md mechanism/verdict sections; fix.diff
PoC changes
none (source-only confirmation for this Info-tier item)
Verified recommended fix
total_acked += (rawp->recsize + 15) & ~15 once; drop the inner increment (keep the xindex advance).
Verdict
source-confirmed (no runtime PoC; deterministic code trace of the cited path:line in the read-only sys/ tree). Code-certain accounting bug (bytessent/journal stats only); no runtime rig (mounting a journal requires the mountctl setup outside this Info batch budget). fix.diff counts the pad size once and stops the inner double-add.
No comments yet.