tar/Fix-buffer-overflow.patch
2019-09-30 11:18:06 -04:00

112 lines
2.4 KiB
Diff

From c7c59b57faa7bd60063f38d3517a8ad50fe1c430 Mon Sep 17 00:00:00 2001
From: Sergey Poznyakoff <gray@gnu.org>
Date: Thu, 20 Dec 2018 20:30:58 +0200
Subject: [PATCH 33/58] Fix buffer overflow
Bug reported in
http://lists.gnu.org/archive/html/bug-tar/2018-12/msg00011.html
* src/xheader.c (xheader_format_name): fix length calculation
---
src/xheader.c | 70 ++++++++++++++++++++++++++++-----------------------
1 file changed, 39 insertions(+), 31 deletions(-)
diff --git a/src/xheader.c b/src/xheader.c
index 6d97131..980f050 100644
--- a/src/xheader.c
+++ b/src/xheader.c
@@ -255,7 +255,7 @@ char *
xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
{
char *buf;
- size_t len = strlen (fmt);
+ size_t len;
char *q;
const char *p;
char *dirp = NULL;
@@ -266,43 +266,51 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
char nbuf[UINTMAX_STRSIZE_BOUND];
char const *nptr = NULL;
- for (p = fmt; *p && (p = strchr (p, '%')); )
+ len = 0;
+ for (p = fmt; *p; p++)
{
- switch (p[1])
+ if (*p == '%' && p[1])
{
- case '%':
- len--;
- break;
-
- case 'd':
- if (st)
+ switch (*++p)
{
- if (!dirp)
- dirp = dir_name (st->orig_file_name);
- dir = safer_name_suffix (dirp, false, absolute_names_option);
- len += strlen (dir) - 2;
- }
- break;
+ case '%':
+ len++;
+ break;
- case 'f':
- if (st)
- {
- base = last_component (st->orig_file_name);
- len += strlen (base) - 2;
- }
- break;
+ case 'd':
+ if (st)
+ {
+ if (!dirp)
+ dirp = dir_name (st->orig_file_name);
+ dir = safer_name_suffix (dirp, false, absolute_names_option);
+ len += strlen (dir);
+ }
+ break;
- case 'p':
- pptr = umaxtostr (getpid (), pidbuf);
- len += pidbuf + sizeof pidbuf - 1 - pptr - 2;
- break;
+ case 'f':
+ if (st)
+ {
+ base = last_component (st->orig_file_name);
+ len += strlen (base);
+ }
+ break;
- case 'n':
- nptr = umaxtostr (n, nbuf);
- len += nbuf + sizeof nbuf - 1 - nptr - 2;
- break;
+ case 'p':
+ pptr = umaxtostr (getpid (), pidbuf);
+ len += pidbuf + sizeof pidbuf - 1 - pptr;
+ break;
+
+ case 'n':
+ nptr = umaxtostr (n, nbuf);
+ len += nbuf + sizeof nbuf - 1 - nptr;
+ break;
+
+ default:
+ len += 2;
+ }
}
- p++;
+ else
+ len++;
}
buf = xmalloc (len + 1);
--
2.19.1