tar was assuming the old behavior of dirtree_path() where there was always a spare byte free at the end. Since removing that seems to have been an intentional change to dirtree_path(), change the caller to resize the string itself.
Caught by ASan. --- toys/posix/tar.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
From cbd9fb596c62030e28406aa230762c34a7a754f0 Mon Sep 17 00:00:00 2001 From: Elliott Hughes <e...@google.com> Date: Tue, 13 Oct 2020 14:16:49 -0700 Subject: [PATCH] tar: fix heap buffer overrun. tar was assuming the old behavior of dirtree_path() where there was always a spare byte free at the end. Since removing that seems to have been an intentional change to dirtree_path(), change the caller to resize the string itself. Caught by ASan. --- toys/posix/tar.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/toys/posix/tar.c b/toys/posix/tar.c index 66547613..ff8d8c4e 100644 --- a/toys/posix/tar.c +++ b/toys/posix/tar.c @@ -203,8 +203,13 @@ static int add_to_tar(struct dirtree *node) while (*lnk=='/') lnk++; } - // Consume the 1 extra byte alocated in dirtree_path() - if (S_ISDIR(st->st_mode) && name[i-1] != '/') strcat(name, "/"); + // ensure there's a trailing / on directories + if (S_ISDIR(st->st_mode) && name[i-1] != '/') { + char *new = xmprintf("%s/", name); + + free(name); + name = hname = new; + } // remove leading / and any .. entries from saved name if (!FLAG(P)) while (*hname == '/') hname++; -- 2.28.0.1011.ga647a8990f-goog
_______________________________________________ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net