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

Reply via email to