abuild-tar: do not read past corrupt tar header

The abuild-tar binary can read past the end of an invalid tar header if
the contained link name does not end with a terminating NUL character.
In this case it reads past the end of hdr.linkname and maybe even past
the end of the header if no further NUL bytes are contained.

The strnlen function is used in apk-tools for such cases as well, so I
recommend to use it here too.

How to reproduce (compile abuild-tar with -fsanitize=address):

cat > poc.tar.b64 << EOF
b3dvAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAAMDAwMDAw
MAAwMDAwMDAwADAwMDAwMDAwMDAwADAwMDAwMDAwMDAwADAwMDAwMAAAMm93b29vb29vb29vb29v
b29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29v
b29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29v
b29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29v
b29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29v
b29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29v
b29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28=
EOF
base64 -d < poc.tar.b64 | abuild-tar --hash
This commit is contained in:
Samanta Navarro 2021-07-24 11:40:17 +00:00 committed by Natanael Copa
parent f97bf6ae8b
commit f8208aded0
1 changed files with 3 additions and 2 deletions

View File

@ -290,7 +290,7 @@ static int do_it(const EVP_MD *md, int cut)
unsigned char digest[EVP_MAX_MD_SIZE];
struct buf data = BUF_INITIALIZER, pax = BUF_INITIALIZER;
struct tar_header hdr, paxhdr;
size_t size, aligned_size;
size_t name_len, size, aligned_size;
int dohash = 0, r, ret = 1;
memset(&paxhdr, 0, sizeof(paxhdr));
@ -322,7 +322,8 @@ static int do_it(const EVP_MD *md, int cut)
EVP_Digest(data.ptr, size, digest, NULL, md, NULL);
add_legacy_checksum(&hdr, md, digest);
} else {
EVP_Digest(hdr.linkname, strlen(hdr.linkname), digest, NULL, md, NULL);
name_len = strnlen(hdr.linkname, sizeof(hdr.linkname));
EVP_Digest(hdr.linkname, name_len, digest, NULL, md, NULL);
}
buf_add_ext_header_hexdump(&pax, checksumhdr, digest, EVP_MD_size(md));