diff options
Diffstat (limited to 'main/apk-tools/tar-parser-overflow.patch')
-rw-r--r-- | main/apk-tools/tar-parser-overflow.patch | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/main/apk-tools/tar-parser-overflow.patch b/main/apk-tools/tar-parser-overflow.patch new file mode 100644 index 00000000000..19dffdbfd43 --- /dev/null +++ b/main/apk-tools/tar-parser-overflow.patch @@ -0,0 +1,65 @@ +From 1423c95eb62afcad29c6a1946de63e5b6a1e804a Mon Sep 17 00:00:00 2001 +From: Ariadne Conill <ariadne@dereferenced.org> +Date: Fri, 2 Apr 2021 13:22:14 -0600 +Subject: [PATCH] archive: more strictly validate tarball headers + +--- + src/archive.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/src/archive.c b/src/archive.c +index 81821dc..80677d0 100644 +--- a/src/archive.c ++++ b/src/archive.c +@@ -60,6 +60,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) ++#define HAS_NULLTERM(a) memchr(a, '\0', sizeof(a)) + + static unsigned int get_octal(char *s, size_t l) + { +@@ -193,6 +194,27 @@ static void handle_extended_header(struct apk_file_info *fi, apk_blob_t hdr) + } + } + ++static int validate_tar_header(struct tar_header *buf) ++{ ++ /* Ensure that fields which should be null-terminated ++ * are null-terminated to use string functions on them. */ ++ if (!HAS_NULLTERM(buf->uname) || !HAS_NULLTERM(buf->gname) || ++ !HAS_NULLTERM(buf->linkname) || !HAS_NULLTERM(buf->magic) || ++ !HAS_NULLTERM(buf->name) || !HAS_NULLTERM(buf->prefix)) { ++ return FALSE; ++ } ++ ++ /* Validate the typeflag field. */ ++ if (!strchr("KLgx01234567", buf->typeflag)) ++ return FALSE; ++ ++ /* Validate the size field. */ ++ if (GET_OCTAL(buf->size) >= SSIZE_MAX - 512) ++ return FALSE; ++ ++ return TRUE; ++} ++ + int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser, + void *ctx, int soft_checksums, struct apk_id_cache *idc) + { +@@ -216,7 +238,12 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser, + memset(&entry, 0, sizeof(entry)); + entry.name = buf.name; + while ((r = apk_istream_read(is, &buf, 512)) == 512) { ++ if (!validate_tar_header(&buf)) { ++ goto err; ++ } ++ + offset += 512; ++ + if (buf.name[0] == '\0') { + if (end) break; + end++; +-- +2.31.0 + |