Dear GNU tar maintainers and Debian Security Team,

Summary: GNU tar 1.35 (latest release; also 1.34 and earlier) reads out of
bounds on the heap when listing an archive containing a malformed dumpdir.
The bug was fixed on upstream master on 2026-07-21 in commit 87819f9
("Check if the dumpdir read from the archive is well-formed before using
it") with no release, no CVE, and no advisory since. Every distribution
still shipping 1.35 or 1.34 is affected. Verified: Debian trixie
1.35+dfsg-3.1, sid 1.35+dfsg-7, and bookworm 1.34+dfsg-1.2+deb12u1 carry
no patches for this (no debian/patches series at all).

Reporter credit requested: JailBr3ak (Nawaf Althurwi)
<[email protected]>. Independent discovery 2026-11-08; the upstream
fix predates my discovery and I do not claim to have prompted it. My
contribution is the shipped-release proof, affected-distro verification,
and disclosure below.

== Root cause ==

dumpdir_decoder() [src/xheader.c:1518-1525 in 1.35] stores the raw PAX
"GNU.dumpdir" value with xmalloc(size)+memcpy and no terminator check.
get_gnu_dumpdir() [src/list.c, GNUTYPE_DUMPDIR path] does the same for
old-GNU 'D' members. Later, dumpdir_size() [src/incremen.c:196-208] walks
the buffer as NUL-separated strings until a double-NUL, with no knowledge
of the allocation size:

    size_t dumpdir_size (const char *p)
    {
      size_t totsize = 0;
      while (*p)
        {
          size_t size = strlen (p) + 1;
          totsize += size;
          p += size;
        }
      return totsize + 1;
    }

An archive whose dumpdir value/member data does not end with the required
double-NUL terminator makes strlen() walk past the end of the heap
allocation. In 1.35 the walk starts inside dumpdir_size() itself (the
while condition dereferences past the block when the last string is
unterminated); list_dumpdir() then prints whatever it walked over.

== Reachability and triggers (both proven) ==

Surface A (PAX extended header) — any tar invocation that parses PAX and
lists verbose dumpdir info:
    tar --incremental -tvvvf crafted.tar
with a PAX record "GNU.dumpdir=d\0dir1\0-" (value not double-NUL
terminated). The value lands in stat_info.dumpdir via dumpdir_decoder;
is_dumpdir becomes true because stat_info->dumpdir != NULL (list.c:729-731).

Surface B (old-GNU 'D' member) — same listing mode:
    tar --incremental -tvvvf crafted2.tar
with a GNUTYPE_DUMPDIR member whose data block lacks the double-NUL.

Both surfaces require --incremental listing with verbosity >= 3 (-tvvv)
to reach list_dumpdir(); plain -t/-x do not reach it. A curious or
forensic listing of an attacker-supplied backup archive is the scenario.

== PoC and observed behavior ==

Repro (deterministic, any of the three variants):
- tar built 1.35 upstream, clang -O1 -g -fsanitize=address:
  ASAN heap-buffer-overflow READ, first bad access exactly at
  end-of-allocation, stacks:
    #0 strlen
    #1 dumpdir_size  src/incremen.c:202 / :200 (direct while-*p read)
    #2 list_archive  src/list.c:331
  Allocation site: xmalloc in dumpdir_decoder (xheader.c:1523) or
  get_gnu_dumpdir (list.c) depending on surface.
- Stock Debian Kali /usr/bin/tar 1.35 (non-ASAN): no crash; the listing
  silently prints bytes from beyond the allocation until the next
  double-NUL in adjacent heap memory. This is an information-disclosure
  pattern on production builds (uncontrolled extent), not a reliable DoS.

== Impact ==

CWE-125 out-of-bounds read on the heap, attacker-controlled archive,
local context (tar runs with the invoking user's privileges; typically
root when inspecting system backups). Demonstrated: ASAN abort on
hardened builds; uncontrolled heap read + print on stock builds. I am NOT
claiming RCE or a controlled-offset leak primitive; extent and disclosed
content depend on heap layout.

== Upstream fix status ==

Already fixed on master: commit 87819f9 (2026-07-21) adds dumpdir_ok()
which rejects dumpdirs whose last two bytes are not 0,0 before use, both
in dumpdir_decoder() and get_gnu_dumpdir(). No GNU tar release has been
made since 1.35 (July 2023), so the fix is unreleased.

Recent CVEs (2026-5704, 2026-18477, 2026-18508) cover different code
paths (hidden file injection, 'X' rename TOCTOU, --one-top-level
hardlink escape) and do not cover this issue.

== Request ==

1. GNU tar: please consider a 1.36 release including 87819f9, or confirm
   the fix is scheduled. If a CVE is warranted, please allocate one for
   the record (CWE-125 heap OOB read, dumpdir_size/dumpdir_decoder/
   get_gnu_dumpdir); if another reporter prompted 87819f9, coordinate
   credit accordingly.
2. Debian: please backport 87819f9 to trixie/sid (and assess bookworm
   1.34). The security tracker has no entry matching this path.

Coordinated disclosure: given the fix already exists publicly on master
and affects released code, I am sending this to the public bug-tar list
(copy to Debian security) rather than requesting an embargo, and do not
intend to publish further details until you respond or a release/DSA
lands, whichever comes first.

Full PoC generator scripts and ASAN transcripts available on request.

Best regards,
JailBr3ak (Nawaf Althurwi)
[email protected]

Attachment: poc-gnutar-dumpdir-oob.md
Description: Binary data

Attachment: gen-pax-dumpdir.py
Description: Binary data

Attachment: gen-dd-direct.py
Description: Binary data

Reply via email to