From f8208aded028c09d40a4e127715e3cdaaab9756f Mon Sep 17 00:00:00 2001 From: Samanta Navarro Date: Sat, 24 Jul 2021 11:40:17 +0000 Subject: [PATCH] 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 --- abuild-tar.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/abuild-tar.c b/abuild-tar.c index d404bbd..c509d63 100644 --- a/abuild-tar.c +++ b/abuild-tar.c @@ -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));