commit:     f2af478770a5a4a3f69ab64f1b5e17c8f7a17050
Author:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Thu Jan 25 04:58:06 2024 +0000
Commit:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Thu Jan 25 04:58:06 2024 +0000
URL:        https://gitweb.gentoo.org/proj/pax-utils.git/commit/?id=f2af4787

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 <AT> gentoo.org>

 paxinc.c | 10 ++++++++--
 paxinc.h |  1 +
 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

Reply via email to