CVE-2026-90556 Overview
CVE-2026-90556 is a heap buffer overflow vulnerability in Freeciv versions before 3.2.6. The flaw resides in the worklist_load() function used by the server to parse savegame files. When a savegame declares a worklist length larger than the fixed array bound of 64 elements (MAX_LEN_WORKLIST), the loader writes past the entries array into adjacent heap-allocated struct fields. Attackers can craft malicious savegame files that corrupt heap memory when a user or server operator loads them. The issue is tracked under [CWE-122: Heap-based Buffer Overflow].
Critical Impact
Loading a malicious savegame can corrupt heap memory in the Freeciv server process, enabling potential code execution in the context of the user or operator running the game.
Affected Products
- Freeciv versions prior to 3.2.6
- Freeciv server component server/savegame/savegame2.c
- Freeciv server component server/savegame/savegame3.c
Discovery Timeline
- 2026-09-12 - CVE-2026-90556 published to NVD
- 2026-09-18 - Last updated in NVD database
Technical Details for CVE-2026-90556
Vulnerability Analysis
The vulnerability exists in the worklist_load() function within both server/savegame/savegame2.c and server/savegame/savegame3.c. Freeciv worklists are backed by a fixed-size array of 64 entries (MAX_LEN_WORKLIST). The loader reads the declared worklist length directly from the savegame file with secfile_lookup_int_default() and stores it in pwl->length without validation. A subsequent for loop iterates from 0 to pwl->length, writing each entry into pwl->entries[i]. When the attacker-controlled length exceeds 64, the loop writes past the array boundary into adjacent heap struct fields, producing a classic out-of-bounds heap write.
Root Cause
The root cause is missing bounds validation on an externally-supplied integer used as a loop counter for a fixed-size heap array. Freeciv trusted the wl_length value from the savegame file rather than clamping it against MAX_LEN_WORKLIST before iterating. This pattern violates the principle of validating all deserialized data before use.
Attack Vector
Exploitation requires an operator or player to load a crafted savegame file, so user interaction is required and the attack vector is local. A malicious savegame can be delivered through community forums, multiplayer server exchanges, or shared game archives. When loaded by a Freeciv server, the oversized wl_length triggers the out-of-bounds write, corrupting adjacent heap objects and potentially leading to arbitrary code execution in the process context.
// Patched savegame code adding bounds validation on wl_length
worklist_init(pwl);
pwl->length = secfile_lookup_int_default(file, 0,
"%s.wl_length", path_str);
+ if (pwl->length > MAX_LEN_WORKLIST) {
+ log_sg("worklist length %d, while MAX_LEN_WORKLIST %d.",
+ pwl->length, MAX_LEN_WORKLIST);
+ pwl->length = MAX_LEN_WORKLIST;
+ } else if (pwl->length > wlist_max_length) {
+ log_sg("worklist length %d, while player's max worklist length %d.",
+ pwl->length, wlist_max_length);
+ }
for (i = 0; i < pwl->length; i++) {
kind = secfile_lookup_str(file, "%s.wl_kind%d", path_str, i);
Source: Freeciv Commit 75ecde3
Detection Methods for CVE-2026-90556
Indicators of Compromise
- Savegame files containing a wl_length value greater than 64 for any worklist path
- Freeciv server crashes or heap corruption errors immediately following a savegame load operation
- Unexpected child processes or network connections initiated by the freeciv-server binary
Detection Strategies
- Statically inspect savegame files for wl_length fields exceeding MAX_LEN_WORKLIST (64) before loading them on production servers
- Run Freeciv builds compiled with AddressSanitizer (ASan) in test environments to surface out-of-bounds writes in worklist_load()
- Monitor process telemetry for abnormal termination signals (SIGSEGV, SIGABRT) originating from freeciv-server during savegame parsing
Monitoring Recommendations
- Log all savegame load events on hosted Freeciv servers and correlate with source IP addresses or user identities
- Alert on unexpected file writes, shell invocations, or outbound connections spawned by the Freeciv server process
- Track deployed Freeciv versions across your environment and flag hosts running versions earlier than 3.2.6
How to Mitigate CVE-2026-90556
Immediate Actions Required
- Upgrade all Freeciv installations to version 3.2.6 or later, which contains the fix in commit 75ecde3
- Restrict savegame uploads and file sharing on public Freeciv servers to trusted operators only
- Isolate Freeciv server processes with reduced OS privileges and filesystem sandboxing until patching is complete
Patch Information
The fix is included in the Freeciv R3_2_6 release and applied via commit 75ecde3. The patch clamps pwl->length to MAX_LEN_WORKLIST when the savegame declares a larger value and logs a warning. Additional context is available in the VulnCheck Freeciv Advisory and Freeciv Issue #2161.
Workarounds
- Do not load savegame files from untrusted sources on unpatched servers
- Run the Freeciv server as an unprivileged user inside a container or chroot to limit the impact of memory corruption
- Manually inspect and reject any savegame where a wl_length field exceeds 64 prior to loading
# Verify installed Freeciv version and reject savegames with oversized worklists
freeciv-server --version
# Quickly scan a savegame for oversized wl_length values before loading
awk -F'=' '/wl_length/ { gsub(/ /, "", $2); if ($2+0 > 64) { print FILENAME": oversized wl_length="$2; exit 1 } }' suspect.sav
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

