Sanitized engineering walkthrough Reviewed

Why a clean compile is not enough: backporting CVE-2026-58470 on 32-bit ARM.

A single upstream security commit can compile without warnings and pass on a 64-bit build host while silently breaking large-file HTTP transfers on a 32-bit ARM device. Here is how target-ABI verification caught a strtol width regression before release review.

Advisory & symbol
CVE-2026-58470 · parse_content_range()
Maintained package
GNU Wget 1.21.4 on pinned Yocto LTS
Target ABI
32-bit ARM Cortex-A5 (ILP32, 64-bit off_t)
Regression prevented
>2 GiB HTTP Content-Range truncation

1. Confirming source applicability before touching the recipe

Pinned Yocto LTS branches commonly ship wget 1.21.4 alongside existing recipe patches for reproducibility and prior advisories (CVE-2024-38428, CVE-2024-10524). Before preparing any change, we reconstruct the exact patched source tree against SDK debug sources to verify whether the reported code path is compiled and reachable.

This case · Confirmed reachable

parse_content_range() in src/http.c

Accumulated HTTP Content-Range byte offsets via unchecked signed math (10 * num + digit). Called directly by Wget's HTTP response handler during ranged transfers.

Contrast · When unreachable

Disabled features stop at VEX

Findings in uncompiled options (excluded via PACKAGECONFIG or uncalled APIs) receive an auditable CVE_STATUS or VEX record rather than an unnecessary binary rebuild.

2. Why cherry-picking only the initial commit breaks 32-bit ARM

Upstream GNU Wget fixed the unchecked loop in commit 43d3ba9336bc using strtol() and errno == ERANGE. That single commit passes on 64-bit build servers yet breaks large-file offsets on 32-bit ARM targets:

x86_64 Build Host · LP64

Masks the truncation

sizeof(long)
64-bit
sizeof(wgint)
64-bit
strtol() max
9.22 EiB (INT64_MAX)
Host unit tests
Pass (>2 GiB OK)
32-bit ARM Target · ILP32

Fails on >2 GiB ranges

sizeof(long)
32-bit
sizeof(wgint)
64-bit (LFS off_t)
strtol() max
2,147,483,647 B (~2 GiB)
ARM unit tests
Fail (ERANGE on >2 GiB)

Upstream subsequently published follow-up commit 01ff771caac1 switching strtol() to strtoll(), and OpenEmbedded-Core paired both commits. Our candidate series preserved both upstream-attributed backports, added boundary guards preventing caller last_byte + 1 overflow at INT64_MAX even when total length is unknown (*), and added 19 boundary unit cases:

/* Enforced 64-bit range invariant on 32-bit ARM (ILP32):
 *   0 <= first_byte <= last_byte < INT64_MAX
 *   entity_length == -1 || last_byte < entity_length <= INT64_MAX
 * Uses strtoll() and prevents caller (last_byte + 1) overflow. */

3. Baseline-vs-candidate validation record

Both baseline and candidate builds were verified across native UndefinedBehaviorSanitizer runs and cross-compiled 32-bit ARM execution under QEMU user mode with the target SDK sysroot:

Verification check Outcome Observed evidence
Unpatched baseline + UBSan Reproduced Signed integer overflow in parse_content_range at http.c:936 (exit 1)
Commit 43d3ba9336bc alone on ARM ABI regression Clean ARM compile, but failed target-ABI range unit group on >2 GiB offsets (exit 1)
Candidate + UBSan native suite Passed 15/15 All 15 unit groups and 29 Content-Range boundary cases passed; zero UBSan faults
Candidate on 32-bit ARM + QEMU Passed 15/15 All 15 unit groups passed with GnuTLS, IPv6, and 64-bit large-file parity intact
HTTP resume integration on ARM Passed 4/4 Passed Test-c.px, Test-c-partial.px, Test-c-full.px, and Test-c-shorter.px
Recipe patch series (--fuzz=0) Clean apply Zero-fuzz patch application on pinned tarball alongside existing recipe patches

Explicit engineering boundary: component validation vs. board sign-off

QEMU user-mode execution proves target-ABI instruction and 32/64-bit type behavior in userspace, catching regressions that host-only builds miss. Full BitBake image assembly, hardware boot, peripheral interfaces, configuration migration, and cryptographic image signing remain distinct release gates under the manufacturer's control. See our responsibility matrix.

Primary technical references

  1. GNU Wget commit 43d3ba9336bc: Fix integer overflow in parse_content_range (CVE-2026-58470) Initial conversion from manual decimal accumulation to strtol().
  2. GNU Wget commit 01ff771caac1: Use strtoll instead of strtol in parse_content_range Follow-up commit restoring 64-bit range parsing on targets with 32-bit long.
  3. Linux kernel documentation: Backporting and conflict resolution Guidance on prerequisite commits, follow-up regression fixes, and runtime validation beyond compilation.
  4. Yocto Project: Checking for Vulnerabilities Guidance on stable-branch backporting, ABI preservation, and CVE status tracking.

Evaluate Firmdura on three CVE cases from your own backlog.

Our Stage 01 baseline applies this exact verification workflow to three upstream-backed user-space CVE cases on one pinned Yocto, Buildroot, OpenWrt, or Debian/CIP configuration for a fixed fee.