diff options
authorTimo Teräs <>2017-06-21 15:12:02 +0300
committerTimo Teräs <>2017-06-23 10:07:44 +0300
commit6b9a07d1ad73dd7ac5349d835c053d76bbfd38f4 (patch)
parent5d439c4739a0c6e2624f7bfab0ebf3588b2f0ac3 (diff)
archive: fix incorrect bounds checking for memory allocation
The value from tar header is unsigned int; keep it casted to unsigned int and size_t instead of (signed) int, otherwise the comparisons fail to do their job properly. Additionally check entry.size against SSIZE_MAX so the rounding up later on is guaranteed to not overflow. Fixes CVE-2017-9669 and CVE-2017-9671. Reported-by: Ariel Zelivansky from Twistlock
1 files changed, 4 insertions, 2 deletions
diff --git a/src/archive.c b/src/archive.c
index 07b33e2..eb9e67c 100644
--- a/src/archive.c
+++ b/src/archive.c
@@ -59,7 +59,7 @@ struct apk_tar_digest_info {
#define GET_OCTAL(s) get_octal(s, sizeof(s))
#define PUT_OCTAL(s,v) put_octal(s, sizeof(s), v)
-static int get_octal(char *s, size_t l)
+static unsigned int get_octal(char *s, size_t l)
apk_blob_t b = APK_BLOB_PTR_LEN(s, l);
return apk_blob_pull_uint(&b, 8);
@@ -133,7 +133,7 @@ static void tar_entry_close(void *stream)
-static int blob_realloc(apk_blob_t *b, int newsize)
+static int blob_realloc(apk_blob_t *b, size_t newsize)
char *tmp;
if (b->len >= newsize) return 0;
@@ -233,6 +233,8 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
teis.mtime = entry.mtime;
apk_xattr_array_resize(&entry.xattrs, 0);
+ if (entry.size >= SSIZE_MAX-512) goto err;
if (paxlen) {
handle_extended_header(&entry, APK_BLOB_PTR_LEN(pax.ptr, paxlen));