diff options
author | Mike Frysinger <vapier@gentoo.org> | 2024-01-24 23:58:06 -0500 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2024-01-24 23:58:06 -0500 |
commit | f2af478770a5a4a3f69ab64f1b5e17c8f7a17050 (patch) | |
tree | 33e6cbbeefb049dc7f60c97f1028f5a866bfd3b7 | |
parent | ar: handle invalid ascii numbers better (diff) | |
download | pax-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.c | 10 | ||||
-rw-r--r-- | paxinc.h | 1 |
2 files changed, 9 insertions, 2 deletions
@@ -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); @@ -48,6 +48,7 @@ typedef struct { const char *filename; size_t skip; char *extfn; + off_t extfn_len; bool verbose; } archive_handle; #else |