From ca9d476ba39d75b9a197f9ae30e5efe2ebafaf3c Mon Sep 17 00:00:00 2001 From: Timo Teräs Date: Wed, 21 Jun 2017 15:25:18 +0300 Subject: archive: validate reading of pax and gnu long filename extensions Detect properly if the file stream gets an error during these read operations. Reported-by: Ariel Zelivansky from Twistlock --- src/archive.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/archive.c b/src/archive.c index eb9e67c..f84e440 100644 --- a/src/archive.c +++ b/src/archive.c @@ -242,9 +242,10 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser, switch (buf.typeflag) { case 'L': /* GNU long name extension */ - if (blob_realloc(&longname, entry.size+1)) goto err_nomem; + if ((r = blob_realloc(&longname, entry.size+1)) != 0 || + (r = is->read(is, longname.ptr, entry.size)) != entry.size) + goto err; entry.name = longname.ptr; - is->read(is, entry.name, entry.size); entry.name[entry.size] = 0; offset += entry.size; entry.size = 0; @@ -291,8 +292,9 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser, case 'x': /* file specific pax header */ paxlen = entry.size; entry.size = 0; - if (blob_realloc(&pax, (paxlen + 511) & -512)) goto err_nomem; - is->read(is, pax.ptr, paxlen); + if ((r = blob_realloc(&pax, (paxlen + 511) & -512)) != 0 || + (r = is->read(is, pax.ptr, paxlen)) != paxlen) + goto err; offset += paxlen; break; default: @@ -318,8 +320,10 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser, if ((offset + toskip) & 511) toskip += 512 - ((offset + toskip) & 511); offset += toskip; - if (toskip != 0) - is->read(is, NULL, toskip); + if (toskip != 0) { + if ((r = is->read(is, NULL, toskip)) != toskip) + goto err; + } } /* Read remaining end-of-archive records, to ensure we read all of @@ -329,20 +333,16 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser, if (buf.name[0] != 0) break; } } - - /* Check that there was no partial (or non-zero) record */ - if (r > 0) r = -EBADMSG; - + if (r == 0) goto ok; err: + /* Check that there was no partial (or non-zero) record */ + if (r >= 0) r = -EBADMSG; +ok: EVP_MD_CTX_cleanup(&teis.mdctx); free(pax.ptr); free(longname.ptr); apk_fileinfo_free(&entry); return r; - -err_nomem: - r = -ENOMEM; - goto err; } int apk_tar_write_entry(struct apk_ostream *os, const struct apk_file_info *ae, -- cgit v1.2.3-60-g2f50