aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2024-01-24 23:58:06 -0500
committerMike Frysinger <vapier@gentoo.org>2024-01-24 23:58:06 -0500
commitf2af478770a5a4a3f69ab64f1b5e17c8f7a17050 (patch)
tree33e6cbbeefb049dc7f60c97f1028f5a866bfd3b7
parentar: handle invalid ascii numbers better (diff)
downloadpax-utils-f2af478770a5a4a3f69ab64f1b5e17c8f7a17050.tar.gz
pax-utils-f2af478770a5a4a3f69ab64f1b5e17c8f7a17050.tar.bz2
pax-utils-f2af478770a5a4a3f69ab64f1b5e17c8f7a17050.zip
ar: handle invalid extended filename offsets
Check the extended filename offset doesn't exceed the size of the extended filename section. Bug: https://bugs.gentoo.org/890579 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r--paxinc.c10
-rw-r--r--paxinc.h1
2 files changed, 9 insertions, 2 deletions
diff --git a/paxinc.c b/paxinc.c
index 5369697..21844d8 100644
--- a/paxinc.c
+++ b/paxinc.c
@@ -126,7 +126,7 @@ close_and_ret:
warn("%s: Duplicate GNU extended filename section", ar->filename);
goto close_and_ret;
}
- len = read_decimal_number_fixed(ret.buf.formatted.size);
+ len = ar->extfn_len = read_decimal_number_fixed(ret.buf.formatted.size);
ar->extfn = xmalloc(sizeof(char) * (len + 1));
if (read(ar->fd, ar->extfn, len) != len)
goto close_and_ret;
@@ -157,7 +157,13 @@ close_and_ret:
warn("%s: GNU extended filename without special data section", ar->filename);
goto close_and_ret;
}
- s = ar->extfn + read_decimal_number(s + 1, sizeof(ret.buf.formatted.name) - 1);
+ /* NB: We NUL terminated extfn above when reading it. */
+ int64_t off = read_decimal_number(s + 1, sizeof(ret.buf.formatted.name) - 1);
+ if (off >= ar->extfn_len) {
+ warn("%s: GNU extended filename has invalid offset", ar->filename);
+ goto close_and_ret;
+ }
+ s = ar->extfn + off;
}
snprintf(ret.name, sizeof(ret.name), "%s:%s", ar->filename, s);
diff --git a/paxinc.h b/paxinc.h
index c8fcf71..b2d2b50 100644
--- a/paxinc.h
+++ b/paxinc.h
@@ -48,6 +48,7 @@ typedef struct {
const char *filename;
size_t skip;
char *extfn;
+ off_t extfn_len;
bool verbose;
} archive_handle;
#else