bsdtar: An error in archive_wstring_append_from_mbs() (archive_string.c) allows out-of-bounds read memory access and subsequently cause a crash
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Libarchive |
New
|
Undecided
|
Unassigned | ||
libarchive (Ubuntu) |
New
|
Undecided
|
Unassigned |
Bug Description
Description:
An error in archive_
Basic Information:
Version of libarchive: libarchive-3.4.0, libarchive-3.4.1dev
How you obtained it: build from source
libarchive-
libarchive-3.4.1dev (https:/
Tested operating system and version: Linux 4.15.0-65-generic x86_64
Tested compilers versions: gcc (version 7.4.0) and clang (version 6.0.0-1ubuntu2)
============
Command to reproduce the bug using valgrind:
$ valgrind -v ./bsdtar -t -f crash_file_1 (in the attachment)
Output (partial):
bsdtar: (null)
bsdtar: Error exit delayed from previous errors.
HEAP SUMMARY:
in use at exit: 0 bytes in 0 blocks
total heap usage: 89 allocs, 89 frees, 285,279 bytes allocated
All heap blocks were freed -- no leaks are possible
ERROR SUMMARY: 2 errors from 1 contexts (suppressed: 0 from 0)
2 errors in context 1 of 1:
Invalid read of size 1
at 0x5081825: utf8_internal_
by 0x5081825: __gconv_
by 0x5116B12: mbrtowc (mbrtowc.c:86)
by 0x14D998: archive_
by 0x14E19B: archive_
by 0x116EF5: archive_
by 0x148297: zip_read_
by 0x1487EC: archive_
by 0x11E1AB: _archive_
by 0x11E2FE: _archive_
by 0x112725: read_archive (read.c:260)
by 0x112E1F: tar_mode_t (read.c:94)
by 0x1114C6: main (bsdtar.c:913)
Address 0x5490f47 is 0 bytes after a block of size 167 alloc'd
at 0x4C2FA3F: malloc (in /usr/lib/
by 0x4C31D84: realloc (in /usr/lib/
by 0x14A6E3: archive_
by 0x14A78A: archive_
by 0x14DF0D: archive_strncat_l (archive_
by 0x14E4C5: archive_strncpy_l (archive_
by 0x14E4C5: archive_
by 0x147D95: zip_read_
by 0x1487EC: archive_
by 0x11E1AB: _archive_
by 0x11E2FE: _archive_
by 0x112725: read_archive (read.c:260)
by 0x112E1F: tar_mode_t (read.c:94)
ERROR SUMMARY: 2 errors from 1 contexts (suppressed: 0 from 0)
-------
Possible cause:
In archive_
int archive_
const char *p, size_t len){
...
const char *mbs = p;
...
while (*mbs && mbs_length > 0) {
...
...
r = mbrtowc(wcs, mbs, wcs_length, &shift_state);
...
if (r == (size_t)-1 || r == (size_t)-2) {
ret_val = -1;
if (errno == EILSEQ) {
++mbs;
--mbs_length;
continue;
} else
break;
}
...
...
}
}
mbrtowc() function is called with the following parameter values: wcs_length = 3, mbs_length = 1, mbs = 0x7ffff6a43ffe "\212".
r = mbrtowc(wcs, mbs, wcs_length, &shift_state);
Here, "mbs" has a length of 1 byte, while, mbrtowc() tends to read 3 bytes (wcs_length = 3), thus resulting into memory out of bounds read.
The program crashes due to memory access violation, which can cause denial of service.
The values {wcs_length = 3, mbs_length = 1} are reached, if return value of mbrtowc() is r = -1 or r = -2 in the previous iteration of the while loop. "mbs" pointer increases (++mbs), and "mbs_length" length decreases (--mbs_length), but wcs_length remains constant (3 bytes in this case).
-------
ProblemType: Bug
DistroRelease: Ubuntu 16.04
Package: bsdtar 3.1.2-11ubuntu0
ProcVersionSign
Uname: Linux 4.4.0-166-generic x86_64
NonfreeKernelMo
ApportVersion: 2.20.1-0ubuntu2.21
Architecture: amd64
CurrentDesktop: Unity
Date: Fri Nov 8 11:58:45 2019
SourcePackage: libarchive
UpgradeStatus: No upgrade log present (probably fresh install)