/tags/1.2.20-3/debian/changelog |
---|
1,3 → 1,71 |
libtar (1.2.20-3) unstable; urgency=low |
* no_maxpathlen.patch: Fix two grave bugs in the patch. First, |
th_get_pathname would only allocate as much memory as was needed for |
the first filename encountered, causing heap corruption when/if |
encountering longer filenames later. Second, two variables were mixed |
up in tar_append_tree(). Also, fix a potential memory leak and trim |
the patch a bit. |
* [SECURITY] CVE-2013-4420.patch: When the prefix field is in use, the |
safer_name_suffix() function should certainly be applied to the |
combination of it and the name field, not just on the name field. |
* th_get_size-unsigned-int.patch: Make the th_get_size() macro cast the |
result from oct_to_int() to unsigned int. This is the right fix for |
bug #725938 on 64-bit systems, where a specially crafted tar file |
would not cause an integer overflow, but a memory allocation of almost |
16 exbibytes, which would certainly fail outright without harm. |
-- Magnus Holmgren <holmgren@debian.org> Sat, 15 Feb 2014 23:51:51 +0100 |
libtar (1.2.20-2) unstable; urgency=low |
* no_static_buffers.patch: avoid using a static buffer in |
th_get_pathname(). Taken from upstream. Needed for no_maxpathlen.patch. |
* no_maxpathlen.patch: Fix FTBFS on Hurd by dynamically allocating path |
names (Closes: #657116). Thanks to Svante Signell and Petter |
Reinholdtsen. |
* [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. |
* Bump Standards-Version to 3.9.5. |
-- Magnus Holmgren <holmgren@debian.org> Sat, 15 Feb 2014 21:49:37 +0100 |
libtar (1.2.20-1) unstable; urgency=high |
* [SECURITY] New upstream release. Fixes CVE-2013-4397: Integer |
overflow (Closes: #725938). |
* Bump Standards-Version to 3.9.4. |
-- Magnus Holmgren <holmgren@debian.org> Thu, 10 Oct 2013 19:20:49 +0200 |
libtar (1.2.19-1) unstable; urgency=low |
* New upstream release. |
-- Magnus Holmgren <holmgren@debian.org> Sun, 05 May 2013 17:59:29 +0200 |
libtar (1.2.16-1) unstable; urgency=low |
* New upstream: Chris Frey has stepped up with the consent of the |
original author, Mark Roth, and published an "official unofficial" git |
repo at http://repo.or.cz/w/libtar.git, which I will use for the time |
being. |
* Updated debian/watch to look for tags and corresponding snapshot |
tarballs at above URL. |
* All patches have been incorporated or (in the case of |
autoreconf.patch) made obsolete upstream. |
* debian/rules: Add build-indep and build-arch targets. |
* Updated debian/copyright. |
* Use dpkg-buildflags to set CFLAGS et al. |
* debian/control: Add VCS fields; bump Standards-Version to 3.9.3. |
-- Magnus Holmgren <holmgren@debian.org> Sat, 23 Jun 2012 01:03:41 +0200 |
libtar (1.2.11-8) unstable; urgency=low |
* libtool.patch: Set SHELL to the configured shell in those Makefile.in |
/tags/1.2.20-3/debian/control |
---|
2,9 → 2,12 |
Section: libs |
Priority: optional |
Maintainer: Magnus Holmgren <holmgren@debian.org> |
Build-Depends: debhelper (>= 7), dh-autoreconf, autoconf, libtool |
Standards-Version: 3.9.2 |
Build-Depends: dpkg-dev (>= 1.15.7), debhelper (>= 7), dh-autoreconf, |
autoconf, libtool |
Standards-Version: 3.9.5 |
Homepage: http://www.feep.net/libtar/ |
Vcs-Browser: http://svn.kibibyte.se/libtar |
Vcs-Svn: svn://svn.kibibyte.se/libtar/trunk |
Package: libtar-dev |
Architecture: any |
/tags/1.2.20-3/debian/patches/libtool.patch |
---|
File deleted |
/tags/1.2.20-3/debian/patches/man_hyphen_minus.patch |
---|
File deleted |
/tags/1.2.20-3/debian/patches/autoreconf.patch |
---|
File deleted |
/tags/1.2.20-3/debian/patches/memleak2.patch |
---|
File deleted |
/tags/1.2.20-3/debian/patches/bad_ptrtoint.patch |
---|
File deleted |
/tags/1.2.20-3/debian/patches/memleak.patch |
---|
File deleted |
/tags/1.2.20-3/debian/patches/CVE-2013-4420.patch |
---|
0,0 → 1,113 |
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,13 +22,42 @@ |
# include <string.h> |
#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) |
{ |
if (t->th_buf.gnu_longname) |
- return t->th_buf.gnu_longname; |
+ return safer_name_suffix(t->th_buf.gnu_longname); |
/* allocate the th_pathname buffer if not already */ |
if (t->th_pathname == NULL) |
@@ -51,7 +80,7 @@ th_get_pathname(TAR *t) |
} |
/* will be deallocated in tar_close() */ |
- return t->th_pathname; |
+ return safer_name_suffix(t->th_pathname); |
} |
--- 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 |
@@ -21,3 +21,4 @@ |
#define TLS_THREAD |
#endif |
+char* safer_name_suffix(char const*); |
--- a/lib/output.c |
+++ b/lib/output.c |
@@ -123,9 +123,9 @@ th_print_long_ls(TAR *t) |
else |
printf(" link to "); |
if ((t->options & TAR_GNU) && t->th_buf.gnu_longlink != NULL) |
- printf("%s", t->th_buf.gnu_longlink); |
+ printf("%s", safer_name_suffix(t->th_buf.gnu_longlink)); |
else |
- printf("%.100s", t->th_buf.linkname); |
+ printf("%.100s", safer_name_suffix(t->th_buf.linkname)); |
} |
putchar('\n'); |
/tags/1.2.20-3/debian/patches/no_maxpathlen.patch |
---|
0,0 → 1,466 |
Author: Svante Signell <svante.signell@telia.com> |
Author: Petter Reinholdtsen <pere@hungry.com> |
Author: Magnus Holmgren <magnus@debian.org> |
Bug-Debian: http://bugs.debian.org/657116 |
Description: Fix FTBFS on Hurd by dynamically allocating path names. |
Depends on no_static_buffers.patch, which introduced the th_pathname field. |
--- a/compat/basename.c |
+++ b/compat/basename.c |
@@ -34,13 +34,25 @@ static char rcsid[] = "$OpenBSD: basenam |
#include <errno.h> |
#include <string.h> |
#include <sys/param.h> |
+#include <stdlib.h> |
char * |
openbsd_basename(path) |
const char *path; |
{ |
- static char bname[MAXPATHLEN]; |
+ static char *bname = NULL; |
+ static size_t allocated = 0; |
register const char *endp, *startp; |
+ int len = 0; |
+ |
+ if (!allocated) { |
+ allocated = 64; |
+ bname = malloc(allocated); |
+ if (!bname) { |
+ allocated = 0; |
+ return NULL; |
+ } |
+ } |
/* Empty or NULL string gets treated as "." */ |
if (path == NULL || *path == '\0') { |
@@ -64,11 +76,19 @@ openbsd_basename(path) |
while (startp > path && *(startp - 1) != '/') |
startp--; |
- if (endp - startp + 1 > sizeof(bname)) { |
- errno = ENAMETOOLONG; |
- return(NULL); |
+ len = endp - startp + 1; |
+ |
+ if (len + 1 > allocated) { |
+ size_t new_allocated = 2*(len+1); |
+ void *new_bname = malloc(new_allocated); |
+ if (!new_bname) |
+ return NULL; |
+ allocated = new_allocated; |
+ free(bname); |
+ bname = new_bname; |
} |
- (void)strncpy(bname, startp, endp - startp + 1); |
- bname[endp - startp + 1] = '\0'; |
+ |
+ (void)strncpy(bname, startp, len); |
+ bname[len] = '\0'; |
return(bname); |
} |
--- a/compat/dirname.c |
+++ b/compat/dirname.c |
@@ -34,13 +34,25 @@ static char rcsid[] = "$OpenBSD: dirname |
#include <errno.h> |
#include <string.h> |
#include <sys/param.h> |
+#include <stdlib.h> |
char * |
openbsd_dirname(path) |
const char *path; |
{ |
- static char bname[MAXPATHLEN]; |
+ static char *bname = NULL; |
+ static size_t allocated = 0; |
register const char *endp; |
+ int len; |
+ |
+ if (!allocated) { |
+ allocated = 64; |
+ bname = malloc(allocated); |
+ if (!bname) { |
+ allocated = 0; |
+ return NULL; |
+ } |
+ } |
/* Empty or NULL string gets treated as "." */ |
if (path == NULL || *path == '\0') { |
--- a/lib/append.c |
+++ b/lib/append.c |
@@ -38,7 +38,7 @@ typedef struct tar_dev tar_dev_t; |
struct tar_ino |
{ |
ino_t ti_ino; |
- char ti_name[MAXPATHLEN]; |
+ char ti_name[]; |
}; |
typedef struct tar_ino tar_ino_t; |
@@ -61,7 +61,7 @@ tar_append_file(TAR *t, const char *real |
libtar_hashptr_t hp; |
tar_dev_t *td = NULL; |
tar_ino_t *ti = NULL; |
- char path[MAXPATHLEN]; |
+ char *path = NULL; |
#ifdef DEBUG |
printf("==> tar_append_file(TAR=0x%lx (\"%s\"), realname=\"%s\", " |
@@ -126,34 +126,39 @@ tar_append_file(TAR *t, const char *real |
} |
else |
{ |
+ const char *name; |
#ifdef DEBUG |
printf("+++ adding entry: device (0x%lx,0x%lx), inode %ld " |
"(\"%s\")...\n", major(s.st_dev), minor(s.st_dev), |
s.st_ino, realname); |
#endif |
- ti = (tar_ino_t *)calloc(1, sizeof(tar_ino_t)); |
+ name = savename ? savename : realname; |
+ ti = (tar_ino_t *)calloc(1, sizeof(tar_ino_t) + strlen(name) + 1); |
if (ti == NULL) |
return -1; |
ti->ti_ino = s.st_ino; |
- snprintf(ti->ti_name, sizeof(ti->ti_name), "%s", |
- savename ? savename : realname); |
+ snprintf(ti->ti_name, strlen(name) + 1, "%s", name); |
libtar_hash_add(td->td_h, ti); |
} |
/* check if it's a symlink */ |
if (TH_ISSYM(t)) |
{ |
- i = readlink(realname, path, sizeof(path)); |
+ if ((path = malloc(s.st_size + 1)) == NULL) |
+ return -1; |
+ i = readlink(realname, path, s.st_size); |
if (i == -1) |
+ { |
+ free(path); |
return -1; |
- if (i >= MAXPATHLEN) |
- i = MAXPATHLEN - 1; |
+ } |
path[i] = '\0'; |
#ifdef DEBUG |
printf(" tar_append_file(): encoding symlink \"%s\" -> " |
"\"%s\"...\n", realname, path); |
#endif |
th_set_link(t, path); |
+ free(path); |
} |
/* print file info */ |
--- a/lib/decode.c |
+++ b/lib/decode.c |
@@ -33,7 +33,8 @@ th_get_pathname(TAR *t) |
/* allocate the th_pathname buffer if not already */ |
if (t->th_pathname == NULL) |
{ |
- t->th_pathname = malloc(MAXPATHLEN * sizeof(char)); |
+ /* Allocate the maximum length of prefix + '/' + name + '\0' */ |
+ t->th_pathname = malloc(155 + 1 + 100 + 1); |
if (t->th_pathname == NULL) |
/* out of memory */ |
return NULL; |
@@ -41,11 +42,11 @@ th_get_pathname(TAR *t) |
if (t->th_buf.prefix[0] == '\0') |
{ |
- snprintf(t->th_pathname, MAXPATHLEN, "%.100s", t->th_buf.name); |
+ sprintf(t->th_pathname, "%.100s", t->th_buf.name); |
} |
else |
{ |
- snprintf(t->th_pathname, MAXPATHLEN, "%.155s/%.100s", |
+ sprintf(t->th_pathname, "%.155s/%.100s", |
t->th_buf.prefix, t->th_buf.name); |
} |
--- a/lib/util.c |
+++ b/lib/util.c |
@@ -15,6 +15,7 @@ |
#include <stdio.h> |
#include <sys/param.h> |
#include <errno.h> |
+#include <stdlib.h> |
#ifdef STDC_HEADERS |
# include <string.h> |
@@ -25,13 +26,15 @@ |
int |
path_hashfunc(char *key, int numbuckets) |
{ |
- char buf[MAXPATHLEN]; |
+ char *buf; |
char *p; |
+ int i; |
- strcpy(buf, key); |
+ buf = strdup(key); |
p = basename(buf); |
- |
- return (((unsigned int)p[0]) % numbuckets); |
+ i = ((unsigned int)p[0]) % numbuckets; |
+ free(buf); |
+ return (i); |
} |
@@ -77,15 +80,26 @@ ino_hash(ino_t *inode) |
int |
mkdirhier(char *path) |
{ |
- char src[MAXPATHLEN], dst[MAXPATHLEN] = ""; |
- char *dirp, *nextp = src; |
- int retval = 1; |
+ char *src, *dst = NULL; |
+ char *dirp, *nextp = NULL; |
+ int retval = 1, len; |
+ |
+ len = strlen(path); |
+ if ((src = strdup(path)) == NULL) |
+ { |
+ errno = ENOMEM; |
+ return -1; |
+ } |
+ nextp = src; |
- if (strlcpy(src, path, sizeof(src)) > sizeof(src)) |
+ /* Make room for // with absolute paths */ |
+ if ((dst = malloc(len + 2)) == NULL) |
{ |
- errno = ENAMETOOLONG; |
+ free(src); |
+ errno = ENOMEM; |
return -1; |
} |
+ dst[0] = '\0'; |
if (path[0] == '/') |
strcpy(dst, "/"); |
@@ -102,12 +116,18 @@ mkdirhier(char *path) |
if (mkdir(dst, 0777) == -1) |
{ |
if (errno != EEXIST) |
+ { |
+ free(src); |
+ free(dst); |
return -1; |
+ } |
} |
else |
retval = 0; |
} |
+ free(src); |
+ free(dst); |
return retval; |
} |
--- a/lib/wrapper.c |
+++ b/lib/wrapper.c |
@@ -16,6 +16,7 @@ |
#include <sys/param.h> |
#include <dirent.h> |
#include <errno.h> |
+#include <stdlib.h> |
#ifdef STDC_HEADERS |
# include <string.h> |
@@ -26,8 +27,8 @@ int |
tar_extract_glob(TAR *t, char *globname, char *prefix) |
{ |
char *filename; |
- char buf[MAXPATHLEN]; |
- int i; |
+ char *buf = NULL; |
+ int i, len; |
while ((i = th_read(t)) == 0) |
{ |
@@ -41,11 +42,25 @@ tar_extract_glob(TAR *t, char *globname, |
if (t->options & TAR_VERBOSE) |
th_print_long_ls(t); |
if (prefix != NULL) |
- snprintf(buf, sizeof(buf), "%s/%s", prefix, filename); |
+ { |
+ len = strlen(prefix) + 1 + strlen(filename); |
+ if ((buf = malloc(len + 1)) == NULL) |
+ return -1; |
+ sprintf(buf, "%s/%s", prefix, filename); |
+ } |
else |
- strlcpy(buf, filename, sizeof(buf)); |
+ { |
+ len = strlen(filename); |
+ if ((buf = malloc(len + 1)) == NULL) |
+ return -1; |
+ strcpy(buf, filename); |
+ } |
if (tar_extract_file(t, buf) != 0) |
+ { |
+ free(buf); |
return -1; |
+ } |
+ free(buf); |
} |
return (i == 1 ? 0 : -1); |
@@ -56,8 +71,9 @@ int |
tar_extract_all(TAR *t, char *prefix) |
{ |
char *filename; |
- char buf[MAXPATHLEN]; |
- int i; |
+ char *buf = NULL; |
+ size_t bufsize = 0; |
+ int i, len; |
#ifdef DEBUG |
printf("==> tar_extract_all(TAR *t, \"%s\")\n", |
@@ -73,15 +89,29 @@ tar_extract_all(TAR *t, char *prefix) |
if (t->options & TAR_VERBOSE) |
th_print_long_ls(t); |
if (prefix != NULL) |
- snprintf(buf, sizeof(buf), "%s/%s", prefix, filename); |
+ { |
+ len = strlen(prefix) + 1 + strlen(filename); |
+ if ((buf = malloc(len + 1)) == NULL) |
+ return -1; |
+ sprintf(buf, "%s/%s", prefix, filename); |
+ } |
else |
- strlcpy(buf, filename, sizeof(buf)); |
+ { |
+ len = strlen(filename); |
+ if ((buf = malloc(len + 1)) == NULL) |
+ return -1; |
+ strcpy(buf, filename); |
+ } |
#ifdef DEBUG |
printf(" tar_extract_all(): calling tar_extract_file(t, " |
"\"%s\")\n", buf); |
#endif |
if (tar_extract_file(t, buf) != 0) |
+ { |
+ free(buf); |
return -1; |
+ } |
+ free(buf); |
} |
return (i == 1 ? 0 : -1); |
@@ -91,11 +121,14 @@ tar_extract_all(TAR *t, char *prefix) |
int |
tar_append_tree(TAR *t, char *realdir, char *savedir) |
{ |
- char realpath[MAXPATHLEN]; |
- char savepath[MAXPATHLEN]; |
+ char *realpath = NULL; |
+ size_t realpathsize = 0; |
+ char *savepath = NULL; |
+ size_t savepathsize = 0; |
struct dirent *dent; |
DIR *dp; |
struct stat s; |
+ int len; |
#ifdef DEBUG |
printf("==> tar_append_tree(0x%lx, \"%s\", \"%s\")\n", |
@@ -122,11 +155,21 @@ tar_append_tree(TAR *t, char *realdir, c |
strcmp(dent->d_name, "..") == 0) |
continue; |
- snprintf(realpath, MAXPATHLEN, "%s/%s", realdir, |
+ len = strlen(realdir) + 1 + strlen(dent->d_name); |
+ if ((realpath = malloc(len + 1)) == NULL) |
+ return -1; |
+ snprintf(realpath, len + 1, "%s/%s", realdir, |
dent->d_name); |
if (savedir) |
- snprintf(savepath, MAXPATHLEN, "%s/%s", savedir, |
+ { |
+ len = strlen(savedir) + 1 + strlen(dent->d_name); |
+ if ((savepath = malloc(len + 1)) == NULL) { |
+ free(realpath); |
+ return -1; |
+ } |
+ snprintf(savepath, len + 1, "%s/%s", savedir, |
dent->d_name); |
+ } |
if (lstat(realpath, &s) != 0) |
return -1; |
@@ -135,13 +178,23 @@ tar_append_tree(TAR *t, char *realdir, c |
{ |
if (tar_append_tree(t, realpath, |
(savedir ? savepath : NULL)) != 0) |
+ { |
+ free(realpath); |
+ free(savepath); |
return -1; |
+ } |
continue; |
} |
if (tar_append_file(t, realpath, |
(savedir ? savepath : NULL)) != 0) |
+ { |
+ free(realpath); |
+ free(savepath); |
return -1; |
+ } |
+ free(realpath); |
+ free(savepath); |
} |
closedir(dp); |
--- a/libtar/libtar.c |
+++ b/libtar/libtar.c |
@@ -111,8 +111,9 @@ create(char *tarfile, char *rootdir, lib |
{ |
TAR *t; |
char *pathname; |
- char buf[MAXPATHLEN]; |
+ char *buf = NULL; |
libtar_listptr_t lp; |
+ int len; |
if (tar_open(&t, tarfile, |
#ifdef HAVE_LIBZ |
@@ -133,17 +134,29 @@ create(char *tarfile, char *rootdir, lib |
{ |
pathname = (char *)libtar_listptr_data(&lp); |
if (pathname[0] != '/' && rootdir != NULL) |
- snprintf(buf, sizeof(buf), "%s/%s", rootdir, pathname); |
+ { |
+ len = strlen(rootdir) + 1 + strlen(pathname); |
+ if ((buf = malloc(len + 1)) == NULL) |
+ return -1; |
+ snprintf(buf, len + 1, "%s/%s", rootdir, pathname); |
+ } |
else |
- strlcpy(buf, pathname, sizeof(buf)); |
+ { |
+ len = strlen(pathname); |
+ if ((buf = malloc(len + 1)) == NULL) |
+ return -1; |
+ strlcpy(buf, pathname, len + 1); |
+ } |
if (tar_append_tree(t, buf, pathname) != 0) |
{ |
fprintf(stderr, |
"tar_append_tree(\"%s\", \"%s\"): %s\n", buf, |
pathname, strerror(errno)); |
tar_close(t); |
+ free(buf); |
return -1; |
} |
+ free(buf); |
} |
if (tar_append_eof(t) != 0) |
/tags/1.2.20-3/debian/patches/no_static_buffers.patch |
---|
0,0 → 1,82 |
From: Kamil Dudka <kdudka@redhat.com> |
Date: Wed, 23 Oct 2013 13:04:22 +0000 (+0200) |
Origin: http://repo.or.cz/w/libtar.git/commitdiff/ec613af2e9371d7a3e1f7c7a6822164a4255b4d1 |
Subject: decode: avoid using a static buffer in th_get_pathname() |
decode: avoid using a static buffer in th_get_pathname() |
A solution suggested by Chris Frey: |
https://lists.feep.net:8080/pipermail/libtar/2013-October/000377.html |
Note this can break programs that expect sizeof(TAR) to be fixed. |
--- a/lib/decode.c |
+++ b/lib/decode.c |
@@ -13,6 +13,7 @@ |
#include <internal.h> |
#include <stdio.h> |
+#include <stdlib.h> |
#include <sys/param.h> |
#include <pwd.h> |
#include <grp.h> |
@@ -26,20 +27,30 @@ |
char * |
th_get_pathname(TAR *t) |
{ |
- static TLS_THREAD char filename[MAXPATHLEN]; |
- |
if (t->th_buf.gnu_longname) |
return t->th_buf.gnu_longname; |
- if (t->th_buf.prefix[0] != '\0') |
+ /* allocate the th_pathname buffer if not already */ |
+ if (t->th_pathname == NULL) |
+ { |
+ t->th_pathname = malloc(MAXPATHLEN * sizeof(char)); |
+ if (t->th_pathname == NULL) |
+ /* out of memory */ |
+ return NULL; |
+ } |
+ |
+ if (t->th_buf.prefix[0] == '\0') |
+ { |
+ snprintf(t->th_pathname, MAXPATHLEN, "%.100s", t->th_buf.name); |
+ } |
+ else |
{ |
- snprintf(filename, sizeof(filename), "%.155s/%.100s", |
+ snprintf(t->th_pathname, MAXPATHLEN, "%.155s/%.100s", |
t->th_buf.prefix, t->th_buf.name); |
- return filename; |
} |
- snprintf(filename, sizeof(filename), "%.100s", t->th_buf.name); |
- return filename; |
+ /* will be deallocated in tar_close() */ |
+ return t->th_pathname; |
} |
--- a/lib/handle.c |
+++ b/lib/handle.c |
@@ -121,6 +121,7 @@ tar_close(TAR *t) |
libtar_hash_free(t->h, ((t->oflags & O_ACCMODE) == O_RDONLY |
? free |
: (libtar_freefunc_t)tar_dev_free)); |
+ free(t->th_pathname); |
free(t); |
return i; |
--- a/lib/libtar.h |
+++ b/lib/libtar.h |
@@ -85,6 +85,9 @@ typedef struct |
int options; |
struct tar_header th_buf; |
libtar_hash_t *h; |
+ |
+ /* introduced in libtar 1.2.21 */ |
+ char *th_pathname; |
} |
TAR; |
/tags/1.2.20-3/debian/patches/series |
---|
1,6 → 1,4 |
libtool.patch |
autoreconf.patch |
memleak2.patch |
#memleak.patch |
bad_ptrtoint.patch |
man_hyphen_minus.patch |
no_static_buffers.patch |
no_maxpathlen.patch |
CVE-2013-4420.patch |
th_get_size-unsigned-int.patch |
/tags/1.2.20-3/debian/patches/th_get_size-unsigned-int.patch |
---|
0,0 → 1,52 |
Origin: http://repo.or.cz/w/libtar.git/commitdiff/e4c1f2974258d6a325622cfd712873d49b5e7a73 |
From: Chris Frey <cdfrey@foursquare.net> |
Date: Thu, 24 Oct 2013 18:52:44 -0400 |
Subject: [PATCH] Change th_get_size() macro to return unsigned int |
On systems where size_t is larger than an int (and larger than |
unsigned int), then in various places in the library, where |
stuff like this happens: |
size_t sz = th_get_size(t); |
then the int value returned from th_get_size() is sign extended to |
some unwieldy amount. |
On 64bit systems, this can yield extremely large values. |
By fixing this problem in the header, and only for th_get_size(), |
we avoid breaking the API of the function call oct_to_int() |
(which arguably should return an unsigned int, since the sscanf() |
it uses expects to yield an unsigned int). We also fix the library, |
which uses th_get_size() internally to assign sizes to size_t. |
The drawback is that not all client code that uses th_get_size() |
will be fixed, until they recompile, but they will automatically |
take advantage of the bugs fixed *inside* the library. |
The remaining th_get_*() functions operate on modes and CRC values |
and the like, and should be fine, remaining as ints. |
Thanks very much to Magnus Holmgren for catching this behaviour. |
https://lists.feep.net:8080/pipermail/libtar/2013-October/000365.html |
--- |
lib/libtar.h | 6 +++++- |
1 file changed, 5 insertions(+), 1 deletion(-) |
diff --git a/lib/libtar.h b/lib/libtar.h |
index 2fefee0..13bb82d 100644 |
--- a/lib/libtar.h |
+++ b/lib/libtar.h |
@@ -185,7 +185,11 @@ int th_write(TAR *t); |
/* decode tar header info */ |
#define th_get_crc(t) oct_to_int((t)->th_buf.chksum) |
-#define th_get_size(t) oct_to_int((t)->th_buf.size) |
+/* We cast from int (what oct_to_int() returns) to |
+ unsigned int, to avoid unwieldy sign extensions |
+ from occurring on systems where size_t is bigger than int, |
+ since th_get_size() is often stored into a size_t. */ |
+#define th_get_size(t) ((unsigned int)oct_to_int((t)->th_buf.size)) |
#define th_get_mtime(t) oct_to_int((t)->th_buf.mtime) |
#define th_get_devmajor(t) oct_to_int((t)->th_buf.devmajor) |
#define th_get_devminor(t) oct_to_int((t)->th_buf.devminor) |
/tags/1.2.20-3/debian/rules |
---|
8,9 → 8,12 |
[ -f debian/autoreconf.before ] || dh_autoreconf |
./configure \ |
--prefix=/usr \ |
--mandir=\$${prefix}/share/man |
--mandir=\$${prefix}/share/man \ |
$(shell dpkg-buildflags --export=configure) |
touch configure-stamp |
build-arch: build |
build-indep: |
build: build-stamp |
build-stamp: configure-stamp |
dh_testdir |
33,7 → 36,7 |
$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp |
binary-indep: build install |
binary-indep: |
binary-arch: install |
dh_testdir |
/tags/1.2.20-3/debian/copyright |
---|
1,13 → 1,15 |
This package was debianized by Glenn McGrath <bug1@debian.org> on |
Sat, 5 Jan 2002 13:24:37 +1100. |
It was downloaded from http://www-dev.cites.uiuc.edu/libtar/ |
It was downloaded from http://repo.or.cz/w/libtar.git; previously from |
http://www.feep.net/libtar/ |
Upstream Author: Mark D. Roth <roth@uiuc.edu> |
Upstream Authors: Mark D. Roth <roth@uiuc.edu> and Chris Frey |
<cdfrey@foursquare.net> |
Copyright: |
Copyright (c) 1998-2002 University of Illinois Board of Trustees |
Copyright (c) 1998-2002 Mark D. Roth |
Copyright (c) 1998-2003 University of Illinois Board of Trustees |
Copyright (c) 1998-2003 Mark D. Roth |
All rights reserved. |
Developed by: Campus Information Technologies and Educational Services, |
41,4 → 43,3 |
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE |
OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. |
/tags/1.2.20-3/debian/watch |
---|
1,3 → 1,6 |
version=3 |
ftp://ftp.feep.net/pub/software/libtar/libtar-(.*).tar.gz |
#ftp://ftp.feep.net/pub/software/libtar/libtar-(.*).tar.gz |
opts=downloadurlmangle=s/tag/snapshot/,filenamemangle=s/.*\/v([\d\.]+)$/libtar-$1.tar.gz/ \ |
http://repo.or.cz/w/libtar.git/shortlog ^.*/v([\d\.]+) |