bsdtar: An error in archive_string_append_from_wcs() (archive_string.c) triggers an out-of-bounds write in heap memory that results into a crash, via a specially crafted archive file. This bug was found using our custom fuzzer.
Basic Information:
versions of libarchive: 3.4.1dev
How you obtained it: built from source
libarchive-3.4.1dev (https://github.com/libarchive/libarchive)
Tested OS: Linux 5.0.0-37-generic x86_64
Tested compiler version : gcc version 7.4.0
What other files were involved?
To trigger the bug, use the the crash file (unzip crash-file.zip) crash-file.zip
===============
Compile with address address sanitizer (-fsanitize=addrsan)
Command to reproduce the bug:
$ ./bsdtar -t -f crash-file
Output (partial):
==2650==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x607000000298 at pc 0x5586b16c5082 bp 0x7ffc3d24a950 sp 0x7ffc3d24a940
WRITE of size 1 at 0x607000000298 thread T0
#0 0x5586b16c5081 in archive_string_append_from_wcs libarchive/archive_string.c:831
#1 0x5586b16c5fd7 in archive_mstring_get_mbs libarchive/archive_string.c:3913
#2 0x5586b162200f in archive_entry_pathname libarchive/archive_entry.c:562
#3 0x5586b16177bb in read_archive tar/read.c:275
#4 0x5586b1618acf in tar_mode_t tar/read.c:94
#5 0x5586b1613c3d in main tar/bsdtar.c:913
#6 0x7fb07ba60b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#7 0x5586b1615a89 in _start (libarchive/bsdtar-addrsan+0x46a89)
0x607000000298 is located 0 bytes to the right of 72-byte region [0x607000000250,0x607000000298)
allocated by thread T0 here:
#0 0x7fb07c9b7f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x5586b16bc2bd in archive_string_ensure libarchive/archive_string.c:314
SUMMARY: AddressSanitizer: heap-buffer-overflow libarchive/archive_string.c:831 in archive_string_append_from_wcs
Shadow bytes around the buggy address:
0x0c0e7fff8000: fa fa fa fa 00 00 00 00 00 00 00 00 00 fa fa fa
0x0c0e7fff8010: fa fa 00 00 00 00 00 00 00 00 00 00 fa fa fa fa
0x0c0e7fff8020: 00 00 00 00 00 00 00 00 00 00 fa fa fa fa 00 00
0x0c0e7fff8030: 00 00 00 00 00 00 00 fa fa fa fa fa fd fd fd fd
0x0c0e7fff8040: fd fd fd fd fd fa fa fa fa fa 00 00 00 00 00 00
=>0x0c0e7fff8050: 00 00 00[fa]fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0e7fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0e7fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0e7fff8080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0e7fff8090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0e7fff80a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==2650==ABORTING
Crash analysis :
In archive_string_append_from_wcs() (archive_string.c), upon execution of the crashing input (crash-file):
archive_string_append_from_wcs(){
....
// Allocated heap memory for as->s is 72 bytes in range (0x607000000250,0x607000000298)
p = as->s + as->length;
...
while (*w != L'\0' && len > 0) {
...
#if HAVE_WCRTOMB
n = wcrtomb(p, *w++, &shift_state); // p = 0x611000000628 --> 0x00, wcrtomb() returns 3, n = 3
#else
n = wctomb(p, *w++);
#endif
if (n == -1) {
if (errno == EILSEQ) {
...
} else
p += n; // p = 0x611000000628 --> 0x00
len--;
}
as->length = p - as->s; // as->length = 72
as->s[as->length] = '\0'; // **Heap overflow** occurs as it tries to write beyond the allocated heap memory
return (ret_val);
}
The text was updated successfully, but these errors were encountered:
mmatuska
added a commit
to mmatuska/libarchive
that referenced
this issue
Dec 28, 2019
When we grow the archive_string buffer, we have to make sure it fits
at least one maximum-sized multibyte character in the current locale
and the null character.
Fixeslibarchive#1298
bsdtar: An error in archive_string_append_from_wcs() (archive_string.c) triggers an out-of-bounds write in heap memory that results into a crash, via a specially crafted archive file. This bug was found using our custom fuzzer.
Basic Information:
versions of libarchive: 3.4.1dev
How you obtained it: built from source
libarchive-3.4.1dev (https://github.com/libarchive/libarchive)
Tested OS: Linux 5.0.0-37-generic x86_64
Tested compiler version : gcc version 7.4.0
What other files were involved?
To trigger the bug, use the the crash file (unzip crash-file.zip)
crash-file.zip
===============
Compile with address address sanitizer (-fsanitize=addrsan)
Command to reproduce the bug:
$ ./bsdtar -t -f crash-file
Output (partial):
Crash analysis :
In archive_string_append_from_wcs() (archive_string.c), upon execution of the crashing input (crash-file):
The text was updated successfully, but these errors were encountered: