Hello,
I am reporting a reproducible crash in Debian wv 1.2.9-9 and upstream wvWare. This one is DoS-class rather than a write primitive, so I am filing it separately from the earlier reports.
`wvGetIntervalBounds()` ends with an unconditional pair of negative-capable indexes (decode_simple.c:758-759):
*fcFirst = wvNormFC (rgfc[nopos - 2], NULL);
*fcLim = wvNormFC (rgfc[nopos - 1], NULL);
When the loop above finds no bracket, `nopos` can be 0 or 1, so `nopos - 2` becomes -1 or -2 and the read runs in front of the `rgfc` array. In the attached sample the read lands on an address in the heap area (ASan: `SEGV on unknown address 0x60240000a0ec`) and the process dies.
Reproduction:
wvRTF cand4.doc
ASan report (first frame):
ERROR: AddressSanitizer: SEGV on unknown address 0x60240000a0ec
#0 wvGetIntervalBounds decode_simple.c:758
#1 wvGetSimpleParaBounds decode_simple.c:683
#2 wvDecodeSimple decode_simple.c:398
Normal build: SIGSEGV, rc=139.
Suggested fix rejects the degenerate case before the tail reads:
if (nopos < 2)
{
*fcFirst = 0;
*fcLim = 0xffffffff;
return (0);
}
With the patch the sample returns 0 and normal documents keep byte-identical RTF output.
This is distinct from CVE-2026-112055 (`wvGetPAPX_FKP` / `wvGetCHPX_FKP`), CVE-2026-112056 (`wvGetSTSH`) and Debian Bug #1148725 (`pap.c` list indices); none of them indexes `rgfc` in `decode_simple.c`.
Confirmed impact is an out-of-bounds read through a computed negative index and process termination; code execution is not claimed.
Please assign a CVE if Debian considers this a vulnerability in the Debian package.
Thanks,
netwind
zwfnetwind@hotmail.com
Reported upstream as well, with the same sample and patch attached: https://github.com/opendocument-app/wvWare/issues/5
Instrumented 1.2.9-9 (`-O0`, probe around the tail of `wvGetIntervalBounds`, no behaviour
change):
OBS nopos=1 rgfc=0x556f5fc1d3c0 m2=00000021 m1=00000000
So the two words that the tail indexes (`rgfc[-2]`, `rgfc[-1]`) are `0x21` and `0x0` ―
neighbouring heap residue, not the paragraph's own bounds. For contrast, a healthy document
yields real values (`j=800 fcFirst=800 fcLim=85c`) at the same call site.
`wvNormFC()` is pure arithmetic (generic.c:117), so those residues are passed through
unchanged: `fcFirst` becomes `0x21` and `fcLim` becomes `0x0`, i.e. an inverted range. The
caller in `decode_simple.c:364` stores them into `para_fcFirst` / `para_fcLim`, compares
them against the current FC and hands them to `wvAssembleSimplePAP()`, so the following PAP
assembly and text walk run against a bogus interval instead of the real one.
The churn is measurable: with a guard that substitutes the sentinel `0` / `0xffffffff` at
that point, the refresh branch at `decode_simple.c:361` fires 9 times on the attached file
versus 1 time on a healthy document ― the bounds state keeps being invalidated and refetched.
Summary of the defect: an out-of-bounds read of two heap words that are then used as file
offsets, producing an inverted paragraph range and, on this input, a SIGSEGV at the read.
The guard patch from the report removes the read and the crash and keeps normal output
byte-identical.