Hello Debian Security Team,

Reporting two memory-safety bugs in GNU cpio 2.15 — the version currently
shipped in Debian (trixie 2.15+dfsg-2, sid 2.15+dfsg-2.1 — verified: the
Debian patch series carries no fix for either). Both are already fixed in
upstream git master, SILENTLY, with no release, no CVE, and no advisory —
so every distro ships them today. I discovered and verified both
independently on 2026-11-07 via AFL++/ASAN fuzzing + stock-binary testing.

Reporter credit requested: JailBr3ak (Nawaf Al-Thurwi)
<[email protected]>

== Bug 1 — stack-buffer-overflow (OOB READ) in from_ascii, CWE-125 ==
Fixed upstream: commit bf16382 (2025-05-29, "Fix invalid memory access").
  src/copyin.c:1000 (2.15):
      for (; *buf == ' '; buf++) { if (buf == end) return 0; }
  The `*buf` dereference happens BEFORE the `buf == end` check. An
  all-spaces field walks past the end of `ascii_header` in
  read_in_new_ascii(). For the last header field (c_chksum) this reads
  stack bytes past the buffer; with all-spaces c_namesize, stack bytes are
  hex-decoded into the filename read length.
  Trigger: `cpio -it` on a crafted newc archive (112-byte PoC; magic
  070701 + 13 all-space 8-char fields + name "x\0"). Deterministic ASAN
  crash: stack-buffer-overflow READ in from_ascii copyin.c:1000.
  Network-reachable surface: cpio is the default parser for rpm2cpio
  pipes, initramfs tools, distro image unpacking.

== Bug 2 — stack buffer overflow (WRITE) in write_out_tar_header, CWE-121 ==
Fixed upstream: commits e8931be (2026-07-25), b5c7d6e (2026-08-05),
e5bb73f (2026-08-29) — none released.
  2.15 code: `strcpy (tar_hdr->uname, name)` with unbounded pw_name into
  uname[32] on the stack of write_out_tar_header().
  Trigger: `cpio -o -H ustar` archiving a file owned by a user with a
  >32-char name (LDAP/AD/containers have these).
  PROOF ON DEBIAN-SHIPPED BINARY: stock /usr/bin/cpio 2.15 (Kali, glibc
  fortify): `*** buffer overflow detected *** : terminated` (SIGABRT).
  Where fortify is absent (some embedded builds), this is a classic
  stack-smash WRITE primitive.

Advisory drafts with full details, PoCs, and upstream-fix analysis
attached (ADVISORY-1-from_ascii-oob.md, ADVISORY-2-uname-stack-smash.md).

Request: please allocate CVEs for both (Debian is well placed as
coordinator; upstream was informed of nothing publicly and the fixes have
no referenced reporter), backport to trixie/sid, and credit as above.
Coordinated disclosure: I will not publish until you say go.

Best regards,
JailBr3ak (Nawaf Al-Thurwi)
[email protected]
# GNU cpio 2.15 — stack-buffer-overflow (OOB read) in from_ascii() parsing newc/crc headers

- **Affected**: GNU cpio 2.15 (current stable release, 2023-11-12) and earlier.
  Shipped as current cpio in Debian 13 trixie (2.15+dfsg-2), Debian sid (2.15+dfsg-2.1,
  verified: no fix in patch series), Ubuntu, Kali, Fedora, Arch, macOS (via old port).
  Fixed upstream in git master commit bf16382 (2025-05-29, "Fix invalid memory
  access") — silently, no release, no CVE, no advisory.
- **Class**: CWE-125 Out-of-bounds Read → stack memory disclosure into parsed
  numeric fields (information disclosure / parse-confusion), deterministic ASAN
  crash (denial of service under hardened/sanitized builds).
- **Attack vector**: network/attacker-supplied archive. `cpio -it` / `cpio -i`
  on a crafted `newc`/`crc` archive. Parsing an archive is the core purpose
  (rpm2cpio-style pipes, distro image unpacking, mailcap handlers).
- **Root cause** (src/copyin.c:1000, from_ascii): the leading-space skip loop
  dereferences `*buf` BEFORE the `buf == end` check:

```c
for (; *buf == ' '; buf++)      /* reads *buf at buf==end first */
  {
    if (buf == end)
      return 0;
  }
```

  For the LAST field of `struct new_ascii_header` (c_chksum, offset 102..109,
  8 bytes) an all-spaces value reads 1 byte past `ascii_header[110]` on the
  stack of `read_in_new_ascii()`. If subsequent stack bytes are spaces, the
  walk continues unbounded across adjacent stack data; those bytes are then
  hex-decoded into `c_chksum`. With all-spaces `c_namesize` the same loop
  parses stack bytes into the allocation length / read length for the
  following filename read (`read_name_from_file`).

- **PoC** (deterministic, 112 bytes): see poc1-newc-allspaces.cpio generator.
  newc header: magic `070701`, ALL 13 numeric fields = 8 spaces, name `x\0`.
  ASAN (cpio 2.15 built -O1 -fsanitize=address):

```
==ERROR: AddressSanitizer: stack-buffer-overflow ... READ of size 1
    #0 from_ascii src/copyin.c:1000
    #1 read_in_new_ascii src/copyin.c:1268
    #2 read_in_header
    #3 process_copy_in src/copyin.c:1455
  'ascii_header' (line 1252) [32, 142) <== access at offset 142 overflows
```

  `cpio -it -F poc1.cpio` suffices; no extraction, no options.

- **Impact**: crash of sanitized builds; stack-byte disclosure into
  attacker-visible fields under normal builds (unpredictable but real for
  repeated/all-spaces headers). Not a write primitive; honest CVSS ~3.3-4.3
  (AV:L/AC:L or AV:N via crafted archive handed to cpio, low confidentiality
  impact). Primary value: memory-safety violation in the default parser of a
  core distro package, fixed silently — distros are unaware.
- **Fix**: upstream bf16382 (`for (; buf < end && *buf == ' '; buf++);`).
  Recommend backport to stable releases and a CVE for the record.
- **Reporter**: JailBr3ak (Nawaf), discovered via AFL++/ASAN differential
  fuzzing campaign, 2026-11-07.
- **Repro**:
  `python3 gen_poc1.py && cpio -it -F poc1-newc-allspaces.cpio`
# GNU cpio 2.15 — stack buffer overflow (WRITE) in write_out_tar_header via long uname/gname

- **Affected**: GNU cpio 2.15 and earlier; fixed in git master e8931be
  (2026-07-25, "Fix possible stack overflow in write_out_tar_header") +
  b5c7d6e (off-by-one in tarnamecpy, 2026-08-05) + e5bb73f (nul-term, 2026-08-29).
  No release carries the fix; Debian trixie/sid 2.15+dfsg-2.1 verified vulnerable.
- **Class**: CWE-121 stack buffer overflow — uncontrolled WRITE length into
  `struct tar_header` fields on the stack of `write_out_tar_header()`.
- **Attack vector** (local, copy-out direction): archiving files whose owner
  user or group has a name longer than 32 chars (uname/gname field size) with
  `cpio -o -H ustar`/`-H tar`. The 2.15 code:

```c
static void set_tar_fname (...)
  ...
  strcpy (tar_hdr->uname, name);   /* name from getpwuid()->pw_name, unbounded */
  strcpy (tar_hdr->gname, name);
```

  `name` is a heap copy of the passwd entry (arbitrary length — user names up
  to login name limits; in containers/AD/LDAP environments 32+ char names
  occur). strcpy smashes subsequent tar_header fields (prefix/pad) and the
  canary.

- **PoC** (poc2-uname-smash.sh): create 40-char username, chown a file,
  `echo f.txt | cpio -o -H ustar -O out.tar`.
  Result on STOCK Kali /usr/bin/cpio 2.15 (glibc _FORTIFY_SOURCE):
  `*** buffer overflow detected *** : terminated` (SIGABRT, rc=134) —
  proven on the shipped, unmodified binary. With longer names the overwrite
  length grows without bound.
- **Impact**: local DoS (proven) + potential control-flow impact where
  fortify is absent (embedded/busybox-style builds, -U_FORTIFY_SOURCE
  distros, older glibc). Honest primary: CWE-121 with proven abort on a
  default distro binary.
- **Fix**: upstream e8931be/b5c7d6e (bounded tarnamecpy). Backport advised.
- **Reporter**: JailBr3ak (Nawaf), 2026-11-07, stock-binary fortify proof.
- **Note**: fix landed 2026-07-25 upstream; if another reporter prompted it,
  coordinate credit — CVE record credits first reporter, this report covers
  the shipped-binary proof + affected-distro mapping.

Attachment: poc2-uname-smash.sh
Description: Bourne shell script

Reply via email to