Greetings,

Following up my own report, seems after I've recovered my savannah.gnu.org account and obtained an authoritative git checkout of tar, bisecting, that this was already fixed upstream just hasn't appeared in a newer release yet.

I tested with inverse logic with a "git bisect run ..." script without overriding the words, so "good" means "bug present" and "bad" mans "bug absent", and 51142180 is actually the *repairing* commit.
git bisect start
# Status: warte auf guten und schlechten Commit
# good: [e545d446dfe6564265cdf4186641ee76f4acc7fa] Version 1.35
git bisect good e545d446dfe6564265cdf4186641ee76f4acc7fa
# Status: warte auf schlechten Commit, 1 guter Commit bekannt
# bad: [2737e1aec0647173e29e334560ef8d123d351dd1] maint: Update library names used by Gnulib.
git bisect bad 2737e1aec0647173e29e334560ef8d123d351dd1
# bad: [f1e4947992aa1b011a9b97c1e5c653eb6c1c5474] Fix string size bound calculation
git bisect bad f1e4947992aa1b011a9b97c1e5c653eb6c1c5474
# bad: [b26e798a0f79b1aedcddf8eac53e05a073333031] xsparse cleanup, including integer overflow
git bisect bad b26e798a0f79b1aedcddf8eac53e05a073333031
# bad: [f0098df0b3616ecbc427d3b4e7a4e5cf953c333c] doc: fix date in example
git bisect bad f0098df0b3616ecbc427d3b4e7a4e5cf953c333c
# good: [a5afb367655ac6dcbc79ba7802a2479044184b38] Fix O(n^2) time bug in --delay-directory-restore
git bisect good a5afb367655ac6dcbc79ba7802a2479044184b38
# bad: [9599d193b84e85bcc0d7015948ed827eb06f1fd1] quote unknown header keywords in diagnostics
git bisect bad 9599d193b84e85bcc0d7015948ed827eb06f1fd1
# bad: [ecdef6677b4eb418f938b6e7a84cb58c696c965e] docs: replace references to fileutils with coreutils.
git bisect bad ecdef6677b4eb418f938b6e7a84cb58c696c965e
# good: [a9a8990fb3b8ff4765151bccea9667e4b6a4fc0c] Bump extrac26 timeout
git bisect good a9a8990fb3b8ff4765151bccea9667e4b6a4fc0c
# bad: [5114218025b4562392dd260e2533d3fa2bc0220e] Fix Savane bug #64581
git bisect bad 5114218025b4562392dd260e2533d3fa2bc0220e
# first bad commit: [5114218025b4562392dd260e2533d3fa2bc0220e] Fix Savane bug #64581


and that's the fix detail, with git describe yielding v1.35-18-g51142180
commit 5114218025b4562392dd260e2533d3fa2bc0220e
Author: Sergey Poznyakoff <g...@gnu.org>
Date:   Tue Aug 22 18:18:31 2023 +0300

   Fix Savane bug #64581

   This reverts commit 4f3824743f50808a0079e6057107de53c4a25f22.

lib/wordsplit.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)



Regards,
Matthias

I wrote shy of two days ago:
Greetings,

passing certain combinations of strings through TAR_OPTIONS (reproducer below) causes tar 1.35 to write outside allocated memory regions, before processing archives.

Cursory testing will not show this bug, but memory error detection will reliably trap the bug IME. All my testing took place on amd64/x86_64 with two different builds and OSes.


The same options through argc/**argv seem to be split properly (which happens inside the shell) and
- in my case passing extra quotes to --mtime was the culprit -
cause complaints that the time format starting with "@ were unrecognized.

All details in the Fedora bug report I've filed (link below), I'll put the relevant info here.
<https://bugzilla.redhat.com/show_bug.cgi?id=2389217>


This shows as "buffer overflow detected" + abort() in fortified builds, or as Invalid write complaint under valgrind, and I surmise the address sanitizer of GCC's or clang's would also complain.

-----
Minimal reproducer with address sanitizer, or fortified builds:

env 'TAR_OPTIONS=--mtime="@1234567890"' \
tar --format=ustar -chf - /tmp >/dev/null

Results in this, on Fedora 42:

*** buffer overflow detected ***: terminated
Aborted (core dumped)

-----
Minimal reproducer with valgrind:

env 'TAR_OPTIONS=--mtime="@1234567890"' \
valgrind --track-origins=yes \
tar --format=ustar -chf - /tmp >/dev/null

-----
Experimenting where the bug is:

BUG: 'TAR_OPTIONS=--mtime="@1234567890"' tar --format=ustar -chf -

SEMI (doesn't seem to scribble memory it doesn't own):
tar --format=ustar '--mtime="@1234567890"' tar --format=ustar -chf -

GOOD:
'TAR_OPTIONS=--mtime=@1234567890' tar --format=ustar -chf -
tar --format=ustar '--mtime=@1234567890' tar --format=ustar -chf -

-----
valgrind trace obtained on FreeBSD, apparently non-fortified build.
It's not too useful by itself, but the "Invalid write" in memcpy are confirmed on a different build with backtrace below.

==48178== Memcheck, a memory error detector
==48178== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al. ==48178== Using Valgrind-3.25.1 and LibVEX; rerun with -h for copyright info
==48178== Command: gtar --format=ustar -chf - /tmp
==48178== ==48178== Invalid write of size 8
==48178== at 0x48569E4: memcpy (vg_replace_strmem.c:1168)
==48178== by 0x24A7CD: ??? (in /usr/local/bin/gtar)
==48178== by 0x24A68A: ??? (in /usr/local/bin/gtar)
==48178== by 0x2498C1: ??? (in /usr/local/bin/gtar)
==48178== by 0x240633: ??? (in /usr/local/bin/gtar)
==48178== by 0x4903E69: __libc_start1 (in /lib/libc.so.7)
==48178== by 0x22041F: ??? (in /usr/local/bin/gtar)
==48178== by 0x4824007: ???
==48178== Address 0x5623c48 is 8 bytes inside a block of size 9 alloc'd
==48178== at 0x484E2E4: malloc (vg_replace_malloc.c:450)
==48178== by 0x24A72E: ??? (in /usr/local/bin/gtar)
==48178== by 0x24A68A: ??? (in /usr/local/bin/gtar)
==48178== by 0x2498C1: ??? (in /usr/local/bin/gtar)
==48178== by 0x240633: ??? (in /usr/local/bin/gtar)
==48178== by 0x4903E69: __libc_start1 (in /lib/libc.so.7)
==48178== by 0x22041F: ??? (in /usr/local/bin/gtar)
==48178== by 0x4824007: ???
==48178== ==48178== Invalid write of size 2
==48178== at 0x4856A85: memcpy (vg_replace_strmem.c:1168)
==48178== by 0x24A7CD: ??? (in /usr/local/bin/gtar)
==48178== by 0x24A68A: ??? (in /usr/local/bin/gtar)
==48178== by 0x2498C1: ??? (in /usr/local/bin/gtar)
==48178== by 0x240633: ??? (in /usr/local/bin/gtar)
==48178== by 0x4903E69: __libc_start1 (in /lib/libc.so.7)
==48178== by 0x22041F: ??? (in /usr/local/bin/gtar)
==48178== by 0x4824007: ???
==48178== Address 0x5623c50 is 7 bytes after a block of size 9 alloc'd


[... more out of bounds reads and writes omitted ...]
-----

The Fedora 42 Linux build aborts due to the fortification which find out that the canaries have been harmed and then abort. Fedora bug report with details filed here for reference:



Backtrace with Fedora's fortified build, which I find usable (indented so Thunderbird won't word-wrap it):

#0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
tid = <optimized out>
ret = 0
pd = <optimized out>
old_mask = {__val = {140543246097462}}
ret = <optimized out>
#1 0x00007fd2c641e163 in __pthread_kill_internal (threadid=<optimized out>, signo=6) at pthread_kill.c:89
No locals.
#2 0x00007fd2c63c4a7e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
ret = <optimized out>
#3 0x00007fd2c63ac6d0 in __GI_abort () at abort.c:77
act = {__sigaction_handler = {sa_handler = 0x559a00000000, sa_sigaction = 0x559a00000000}, sa_mask = {__val = {0, 94121436579136, 8, 140734169646992, 779909072403883264, 94121436579136, 0, 0, 335544320, 140543245700016, 65536, 94119913324560, 140543246595678, 4096, 140543247367818, 976259312}}, sa_flags = 1371333888, sa_restorer = 0x7fd2c655e2da} #4 0x00007fd2c63ad6f3 in __libc_message_impl (fmt=fmt@entry=0x7fd2c655e2c3 "*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:134 ap = {{gp_offset = 16, fp_offset = 32767, overflow_arg_area = 0x7fff3a3087f0, reg_save_area = 0x7fff3a308780}}
fd = 2
iov = {{iov_base = 0x7fd2c655e2c3, iov_len = 4}, {iov_base = 0x7fd2c655e2aa, iov_len = 24}, {iov_base = 0x7fd2c655e2c9, iov_len = 17}, {iov_base = 0x0, iov_len = 94121436574688}, {iov_base = 0x559a5acaf680, iov_len = 0}, {iov_base = 0x2475acaf3e0, iov_len = 40}, {iov_base = 0x559a5acb1550, iov_len = 0}}
iovcnt = <optimized out>
total = <optimized out>
cp = <optimized out>
#5 0x00007fd2c64aa549 in __GI___fortify_fail (msg=msg@entry=0x7fd2c655e2aa "buffer overflow detected") at fortify_fail.c:24
No locals.
#6 0x00007fd2c64a9ea4 in __GI___chk_fail () at chk_fail.c:28
No locals.
#7 0x0000559a384b0c6e in memcpy (__dest=<optimized out>, __src=<optimized out>, __len=11) at /usr/include/bits/string_fortified.h:29
No locals.
#8 coalesce_segment (wsp=wsp@entry=0x7fff3a3089b0, node=node@entry=0x559a5acb1580) at ../lib/wordsplit.c:598
next = 0x0
str = <optimized out>
slen = 11
p = 0x559a5acb15b0
end = 0x559a5acb15b0
len = 8
buf = 0x559a5acb05a0 "--mtime="
cur = <optimized out>
#9 0x0000559a384b574a in wsnode_coalesce (wsp=0x7fff3a3089b0) at ../lib/wordsplit.c:675
p = 0x559a5acb1580
#10 wordsplit_process_list (wsp=0x7fff3a3089b0, start=<optimized out>) at ../lib/wordsplit.c:2379
p = 0x559a384e5d10 <exptab+48>
#11 0x0000559a384bc15b in wordsplit_run (lvl=0, command=0x7fff3a30a4cf "--owner=0 --group=0 --sort=name --mtime=\"@1752234285\"", length=<optimized out>, wsp=0x7fff3a3089b0, flags=33558086) at ../lib/wordsplit.c:2434
rc = <optimized out>
start = 0
#12 wordsplit_len (command=0x7fff3a30a4cf "--owner=0 --group=0 --sort=name --mtime=\"@1752234285\"", length=<optimized out>, wsp=0x7fff3a3089b0, flags=33558086) at ../lib/wordsplit.c:2444
No locals.
#13 wordsplit (command=0x7fff3a30a4cf "--owner=0 --group=0 --sort=name --mtime=\"@1752234285\"", ws=0x7fff3a3089b0, flags=33558086) at ../lib/wordsplit.c:2450
No locals.
#14 0x0000559a3847f47e in parse_default_options (args=0x7fff3a308980) at /usr/src/debug/tar-1.35-5.fc42.x86_64/src/tar.c:2256
opts = <optimized out>
ws = {ws_wordc = 0, ws_wordv = 0x0, ws_offs = 1, ws_wordn = 0, ws_flags = 33558086, ws_options = 1632, ws_maxwords = 140543247636624, ws_wordi = 0, ws_delim = 0x559a384d0cd1 " \t\n", ws_comment = 0x0, ws_escape = { 0x559a384e5c90 <wordsplit_c_escape_tab> "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v", 0x559a384e5c90 <wordsplit_c_escape_tab> "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v"}, ws_alloc_die = 0x559a384af9c0 <_wsplt_alloc_die>, ws_error = 0x559a384b09f0 <_wsplt_error>, ws_debug = 0x0, ws_env = 0x15, ws_envbuf = 0x100a, ws_envidx = 255, ws_envsiz = 4185718668, ws_getvar = 0x0, ws_closure = 0x0, ws_command = 0xf97cff8c, ws_input = 0x7fff3a30a4cf "--owner=0 --group=0 --sort=name --mtime=\"@1752234285\"", ws_len = 53, ws_endp = 53, ws_errno = 0, ws_usererr = 0x0, ws_head = 0x559a5acb14f0, ws_tail = 0x559a5acb15b0, ws_lvl = 0} loc = {source = OPTS_ENVIRON, name = 0x559a384d0d6f "TAR_OPTIONS", line = 0, prev = 0x0}
save_loc_ptr = <optimized out>
#15 decode_options (argc=5, argv=0x7fff3a308bf8) at /usr/src/debug/tar-1.35-5.fc42.x86_64/src/tar.c:2378
idx = 32767
loc = {source = OPTS_COMMAND_LINE, name = 0x0, line = 0, prev = 0x0}
args = {loc = 0x7fff3a308940, textual_date = 0x0, o_option = false, pax_option = false, compress_autodetect = false, backup_suffix_string = 0x0, version_control_string = 0x0} #16 main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/tar-1.35-5.fc42.x86_64/src/tar.c:2792
No locals.

Let me know if you need anything else.

Best regards,
Matthias Andree




Reply via email to