aethersdr / aethersdr/AetherSDR
AdifParser: signed-integer-overflow on crafted ADIF field length
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 221
- Forks
- 117
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 299
Description
Claude here (AI dev partner) — found this while sanitizer-fuzzing the ADIF import path.
Summary
AdifParser::extractField computes start + len on two ints, where len
comes straight from the ADIF field-length token (m.captured(1).toInt()). A
crafted length near INT_MAX overflows the signed addition — undefined
behavior — when importing a malformed .adi file. The bounds check that
follows (start + len > block.length()) is defeated by the overflow, though no
out-of-bounds read/write actually results because QString::mid clamps.
Repro
Import this .adi (or feed it to AdifParser::parseFile):
<EOH>
<CALL:2147483647>G3ABC<BAND:3>20m<MODE:2>CW<EOR>
Under -fsanitize=undefined:
src/core/AdifParser.cpp:28:15: runtime error: signed integer overflow:
18 + 2147483647 cannot be represented in type 'int'
(Line 28 as of current main — the if (start + len > block.length()) line in
extractField.)
Impact
Undefined behavior on importing an untrusted or corrupted ADIF log. Not an
exploitable out-of-bounds write (Qt's mid is memory-safe), but UB is
compiler/optimization-dependent and the length guard is silently bypassed for
oversized lengths.
Suggested fix
Compare against the remaining space instead of adding (also guards a negative
length defensively):
// extractField, replacing: if (start + len > block.length()) return {};
if (len < 0 || len > block.length() - start) return {};
return block.mid(start, len);
Verified: with this change, the crafted input above parses cleanly (0 records,
no sanitizer trip) while a normal ADIF export still parses all records — the fix
removes the UB and preserves valid parsing.
73, Jeremy KK7GWY & Claude (AI dev partner)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/core/AdifParser.cpp at AdifParser::extractField and inspect the length parsing and bounds check described at line 28; use parseFile with the crafted .adi input under an undefined-behavior sanitizer. Done means oversized or negative lengths are rejected without a sanitizer report while normal ADIF exports still parse all records.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100