Hello!
Using cpio and building it with the ASAN sanitizer I have found a bug
in tar.c. Running cpio with the -oA0 and -HustaR flags on a file
containing a information, as shown below, stack-buffer overflow error
occurs in the getuidbyname() function.
I think the problem is that the fields of struct tar_hdr may not be
null-terminated, because setting 0 at the end of uname and gname
fixes this error.
diff --git a/src/tar.c b/src/tar.c
index 493f299..11473b2 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -317,6 +317,8 @@ read_in_tar_header (struct cpio_file_stat *file_hdr,
int in_des)
file_hdr->c_nlink = 1;
file_hdr->c_mode = FROM_OCTAL (tar_hdr->mode);
file_hdr->c_mode = file_hdr->c_mode & 07777;
+ tar_hdr->uname[31] = 0;
+ tar_hdr->gname[31] = 0;
/* Debian hack: This version of cpio uses the -n flag also to extract
tar archives using the numeric UID/GID instead of the user/group
names in /etc/passwd and /etc/groups. (98/10/15) -BEM */
Here is the stacktrace:
=================================================================
==1727975==ERROR: AddressSanitizer: stack-buffer-overflow on address
0x76cd87d00620 at pc 0x641cdfb0dca1 bp 0x7fffd3a06b50 sp 0x7fffd3a06318
READ of size 248 at 0x76cd87d00620 thread T0
#0 0x641cdfb0dca0 in getpwnam (/cpio-/src/cpio+0xadca0) (BuildId:
44370855dcea4a1d8855cc797e231f8bef3c1cca)
#1 0x641cdfc54f08 in getuidbyname /cpio-/src/idcache.c:105:11
#2 0x641cdfc2b608 in read_in_tar_header /cpio-/src/tar.c:324:15
#3 0x641cdfbcb510 in read_in_header /cpio-/src/copyin.c:1105:7
#4 0x641cdfbd7228 in process_copy_in /cpio-/src/copyin.c:1451:7
#5 0x641cdfbfc3ea in process_copy_out /cpio-/src/copyout.c:628:7
#6 0x641cdfc25a49 in main /cpio-/src/main.c:810:3
#7 0x76cd89ef909a in __libc_start_main
/opt/build/glibc-2.28/csu/../csu/libc-start.c:308:16
#8 0x641cdfae4a19 in _start (/cpio-/src/cpio+0x84a19) (BuildId:
44370855dcea4a1d8855cc797e231f8bef3c1cca)
Address 0x76cd87d00620 is located in stack of thread T0 at offset 544 in
frame
#0 0x641cdfc2a7ef in read_in_tar_header /cpio-/src/tar.c:253
Steps to reproduce this error:
1. Build the project with AddressSanitizer:
export CC=clang
export CXX=clang++
export CFLAGS="-g -O0 -fsanitize=address"
export CXXFLAGS="-g -O0 -fsanitize=address"
./bootstrap
./configure --enable-mt --build x86_64-linux-gnu CFLAGS="$CFLAGS"
make
2. Create files, that contains information, like this:
echo -e
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\`aaaaaaaaaaaaaaaaaaaaaaaEffv000aa\x81\x81aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0"
> out_archive
echo -e "0\0" > in_archive
3. Run cpio as follows:
cat in_archive | ./cpio -oA0 -HustaR -O out_archive
4. You will get an ASAN report