summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-12-20 20:30:58 +0200
committerSergey Poznyakoff <gray@gnu.org>2018-12-21 13:54:11 +0200
commitc7c59b57faa7bd60063f38d3517a8ad50fe1c430 (patch)
tree5ae2e28de412b5e759ec019572b51ff8e2df7556
parenteae48289c0848c5812644f20dbb1b39fb117a8f6 (diff)
downloadtar-c7c59b57faa7bd60063f38d3517a8ad50fe1c430.tar.gz
tar-c7c59b57faa7bd60063f38d3517a8ad50fe1c430.tar.bz2
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
-rw-r--r--src/xheader.c70
1 files changed, 39 insertions, 31 deletions
diff --git a/src/xheader.c b/src/xheader.c
index 6d97131d..980f0504 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);

Return to:

Send suggestions and report system problems to the System administrator.