aethersdr / aethersdr/AetherSDR

AdifParser: signed-integer-overflow on crafted ADIF field length

Open Beginner friendly
#4,411 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug external devices good first issue maintainer-review priority: low
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.