Subversion Repositories libtar

Compare Revisions

Ignore whitespace Rev 34 → Rev 35

/branches/wheezy/debian/changelog
1,3 → 1,15
libtar (1.2.16-1+deb7u2) wheezy-security; urgency=low
 
* [SECURITY] CVE-2013-4420.patch: Strip out leading slashes and any
pathname prefix containing ".." components (Closes: #731860). This is
done in th_get_pathname() (as well as to symlink targets when
extracting symlinks), not merely when extracting files, which means
applications calling that function will not see the stored
filename. There is no way to disable this behaviour, but it can be
expected that one will be provided when the issue is solved upstream.
 
-- Magnus Holmgren <holmgren@debian.org> Sun, 16 Feb 2014 19:12:18 +0100
 
libtar (1.2.16-1+deb7u1) wheezy-security; urgency=low
 
* [SECURITY] size_t-overflow_cve-2013-4397.patch: Fix CVE-2013-4397:
/branches/wheezy/debian/patches/CVE-2013-4420.patch
0,0 → 1,104
Author: Raphael Geissert <geissert@debian.org>
Bug-Debian: https://bugs.debian.org/731860
Description: Avoid directory traversal when extracting archives
by skipping over leading slashes and any prefix containing ".." components.
Forwarded: yes
 
--- a/lib/decode.c
+++ b/lib/decode.c
@@ -22,6 +22,36 @@
#endif
+char *
+safer_name_suffix (char const *file_name)
+{
+ char const *p, *t;
+ p = t = file_name;
+ while (*p == '/') t = ++p;
+ while (*p)
+ {
+ while (p[0] == '.' && p[0] == p[1] && p[2] == '/')
+ {
+ p += 3;
+ t = p;
+ }
+ /* advance pointer past the next slash */
+ while (*p && (p++)[0] != '/');
+ }
+
+ if (!*t)
+ {
+ t = ".";
+ }
+
+ if (t != file_name)
+ {
+ /* TODO: warn somehow that the path was modified */
+ }
+ return (char*)t;
+}
+
+
/* determine full path name */
char *
th_get_pathname(TAR *t)
@@ -29,17 +59,17 @@ th_get_pathname(TAR *t)
static char filename[MAXPATHLEN];
if (t->th_buf.gnu_longname)
- return t->th_buf.gnu_longname;
+ return safer_name_suffix(t->th_buf.gnu_longname);
if (t->th_buf.prefix[0] != '\0')
{
snprintf(filename, sizeof(filename), "%.155s/%.100s",
t->th_buf.prefix, t->th_buf.name);
- return filename;
+ return safer_name_suffix(filename);
}
snprintf(filename, sizeof(filename), "%.100s", t->th_buf.name);
- return filename;
+ return safer_name_suffix(filename);
}
--- a/lib/extract.c
+++ b/lib/extract.c
@@ -298,14 +298,14 @@ tar_extract_hardlink(TAR * t, char *real
if (mkdirhier(dirname(filename)) == -1)
return -1;
libtar_hashptr_reset(&hp);
- if (libtar_hash_getkey(t->h, &hp, th_get_linkname(t),
+ if (libtar_hash_getkey(t->h, &hp, safer_name_suffix(th_get_linkname(t)),
(libtar_matchfunc_t)libtar_str_match) != 0)
{
lnp = (char *)libtar_hashptr_data(&hp);
linktgt = &lnp[strlen(lnp) + 1];
}
else
- linktgt = th_get_linkname(t);
+ linktgt = safer_name_suffix(th_get_linkname(t));
#ifdef DEBUG
printf(" ==> extracting: %s (link to %s)\n", filename, linktgt);
@@ -343,9 +343,9 @@ tar_extract_symlink(TAR *t, char *realna
#ifdef DEBUG
printf(" ==> extracting: %s (symlink to %s)\n",
- filename, th_get_linkname(t));
+ filename, safer_name_suffix(th_get_linkname(t)));
#endif
- if (symlink(th_get_linkname(t), filename) == -1)
+ if (symlink(safer_name_suffix(th_get_linkname(t)), filename) == -1)
{
#ifdef DEBUG
perror("symlink()");
--- a/lib/internal.h
+++ b/lib/internal.h
@@ -15,3 +15,4 @@
#include <libtar.h>
+char* safer_name_suffix(char const*);
/branches/wheezy/debian/patches/series
1,0 → 0,0
size_t-overflow_cve-2013-4397.patch
CVE-2013-4420.patch