From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from ptx.hi.pengutronix.de ([2001:6f8:1178:2:5054:ff:fec0:8e10] ident=Debian-exim) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1WLco4-0007sl-H8 for ptxdist@pengutronix.de; Thu, 06 Mar 2014 19:14:08 +0100 Received: from mol by ptx.hi.pengutronix.de with local (Exim 4.80) (envelope-from ) id 1WLco4-0002Md-FV for ptxdist@pengutronix.de; Thu, 06 Mar 2014 19:14:08 +0100 Date: Thu, 6 Mar 2014 19:14:08 +0100 From: Michael Olbrich Message-ID: <20140306181408.GS32080@pengutronix.de> References: <1393160492-30990-1-git-send-email-post@lespocky.de> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1393160492-30990-1-git-send-email-post@lespocky.de> Subject: Re: [ptxdist] [PATCH] libtar: add as new package Reply-To: ptxdist@pengutronix.de List-Id: PTXdist Development Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: ptxdist-bounces@pengutronix.de Errors-To: ptxdist-bounces@pengutronix.de To: ptxdist@pengutronix.de On Sun, Feb 23, 2014 at 02:01:32PM +0100, Alexander Dahl wrote: > libtar is a C library for manipulating POSIX tar files. It handles > adding and extracting files to/from a tar archive. I reviewed the > current Debian patches for usefulness and added all of them. Since the > "official unofficial" way (maintainer's words) to get new releases is > Git only I used the ptxdist mechanism for creating a tarball from a git > clone in get stage. > > Signed-off-by: Alexander Dahl Thanks, applied. Michael > --- > ...d-using-a-static-buffer-in-th_get_pathnam.patch | 92 ++++ > patches/libtar-1.2.20/0002-no_maxpathlen.patch | 487 ++++++++++++++++++++ > patches/libtar-1.2.20/0003-CVE-2013-4420.patch | 126 +++++ > ...-th_get_size-macro-to-return-unsigned-int.patch | 51 ++ > patches/libtar-1.2.20/autogen.sh | 1 + > patches/libtar-1.2.20/series | 7 + > rules/libtar.in | 11 + > rules/libtar.make | 62 +++ > 8 files changed, 837 insertions(+) > create mode 100644 patches/libtar-1.2.20/0001-decode-avoid-using-a-static-buffer-in-th_get_pathnam.patch > create mode 100644 patches/libtar-1.2.20/0002-no_maxpathlen.patch > create mode 100644 patches/libtar-1.2.20/0003-CVE-2013-4420.patch > create mode 100644 patches/libtar-1.2.20/0004-Change-th_get_size-macro-to-return-unsigned-int.patch > create mode 120000 patches/libtar-1.2.20/autogen.sh > create mode 100644 patches/libtar-1.2.20/series > create mode 100644 rules/libtar.in > create mode 100644 rules/libtar.make > > diff --git a/patches/libtar-1.2.20/0001-decode-avoid-using-a-static-buffer-in-th_get_pathnam.patch b/patches/libtar-1.2.20/0001-decode-avoid-using-a-static-buffer-in-th_get_pathnam.patch > new file mode 100644 > index 0000000..7664f1d > --- /dev/null > +++ b/patches/libtar-1.2.20/0001-decode-avoid-using-a-static-buffer-in-th_get_pathnam.patch > @@ -0,0 +1,92 @@ > +From: Kamil Dudka > +Date: Wed, 23 Oct 2013 13:04:22 +0200 > +Subject: [PATCH] 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. > +--- > + lib/decode.c | 25 ++++++++++++++++++------- > + lib/handle.c | 1 + > + lib/libtar.h | 3 +++ > + 3 files changed, 22 insertions(+), 7 deletions(-) > + > +diff --git a/lib/decode.c b/lib/decode.c > +index c16ea2d..35312be 100644 > +--- a/lib/decode.c > ++++ b/lib/decode.c > +@@ -13,6 +13,7 @@ > + #include > + > + #include > ++#include > + #include > + #include > + #include > +@@ -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; > + } > + > + > +diff --git a/lib/handle.c b/lib/handle.c > +index 33a262c..9faf2ed 100644 > +--- 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; > +diff --git a/lib/libtar.h b/lib/libtar.h > +index 55f509a..5993cd2 100644 > +--- 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; > + > diff --git a/patches/libtar-1.2.20/0002-no_maxpathlen.patch b/patches/libtar-1.2.20/0002-no_maxpathlen.patch > new file mode 100644 > index 0000000..90a95fb > --- /dev/null > +++ b/patches/libtar-1.2.20/0002-no_maxpathlen.patch > @@ -0,0 +1,487 @@ > +From: unknown author > +Date: Thu, 20 Feb 2014 13:49:38 +0100 > +Subject: [PATCH] no_maxpathlen > + > +--- > + compat/basename.c | 32 +++++++++++++++++----- > + compat/dirname.c | 14 +++++++++- > + lib/append.c | 21 +++++++++------ > + lib/decode.c | 7 ++--- > + lib/util.c | 38 +++++++++++++++++++------- > + lib/wrapper.c | 77 ++++++++++++++++++++++++++++++++++++++++++++--------- > + libtar/libtar.c | 19 ++++++++++--- > + 7 files changed, 166 insertions(+), 42 deletions(-) > + > +diff --git a/compat/basename.c b/compat/basename.c > +index 2ac1e13..93c75e6 100644 > +--- a/compat/basename.c > ++++ b/compat/basename.c > +@@ -34,13 +34,25 @@ static char rcsid[] = "$OpenBSD: basename.c,v 1.4 1999/05/30 17:10:30 espie Exp > + #include > + #include > + #include > ++#include > + > + 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); > + } > +diff --git a/compat/dirname.c b/compat/dirname.c > +index 986db4a..987b46e 100644 > +--- a/compat/dirname.c > ++++ b/compat/dirname.c > +@@ -34,13 +34,25 @@ static char rcsid[] = "$OpenBSD: dirname.c,v 1.4 1999/05/30 17:10:30 espie Exp $ > + #include > + #include > + #include > ++#include > + > + 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') { > +diff --git a/lib/append.c b/lib/append.c > +index 13e1ace..3628d87 100644 > +--- 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 *realname, const char *savename) > + 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 *realname, const char *savename) > + } > + 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 */ > +diff --git a/lib/decode.c b/lib/decode.c > +index 35312be..df62bec 100644 > +--- 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); > + } > + > +diff --git a/lib/util.c b/lib/util.c > +index 31e8315..2c9b0fa 100644 > +--- a/lib/util.c > ++++ b/lib/util.c > +@@ -15,6 +15,7 @@ > + #include > + #include > + #include > ++#include > + > + #ifdef STDC_HEADERS > + # include > +@@ -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; > + } > + > +diff --git a/lib/wrapper.c b/lib/wrapper.c > +index 4cd0652..897ee44 100644 > +--- a/lib/wrapper.c > ++++ b/lib/wrapper.c > +@@ -16,6 +16,7 @@ > + #include > + #include > + #include > ++#include > + > + #ifdef STDC_HEADERS > + # include > +@@ -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, 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); > ++ } > + 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, char *savedir) > + 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, char *savedir) > + { > + 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); > +diff --git a/libtar/libtar.c b/libtar/libtar.c > +index 9fa92b2..f4967e8 100644 > +--- a/libtar/libtar.c > ++++ b/libtar/libtar.c > +@@ -111,8 +111,9 @@ create(char *tarfile, char *rootdir, libtar_list_t *l) > + { > + 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, libtar_list_t *l) > + { > + 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) > diff --git a/patches/libtar-1.2.20/0003-CVE-2013-4420.patch b/patches/libtar-1.2.20/0003-CVE-2013-4420.patch > new file mode 100644 > index 0000000..7adbaed > --- /dev/null > +++ b/patches/libtar-1.2.20/0003-CVE-2013-4420.patch > @@ -0,0 +1,126 @@ > +From: unknown author > +Date: Thu, 20 Feb 2014 13:49:38 +0100 > +Subject: [PATCH] CVE-2013-4420 > + > +--- > + lib/decode.c | 33 +++++++++++++++++++++++++++++++-- > + lib/extract.c | 8 ++++---- > + lib/internal.h | 1 + > + lib/output.c | 4 ++-- > + 4 files changed, 38 insertions(+), 8 deletions(-) > + > +diff --git a/lib/decode.c b/lib/decode.c > +index df62bec..0b75be1 100644 > +--- a/lib/decode.c > ++++ b/lib/decode.c > +@@ -22,13 +22,42 @@ > + # include > + #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); > + } > + > + > +diff --git a/lib/extract.c b/lib/extract.c > +index 36357e7..627e05f 100644 > +--- a/lib/extract.c > ++++ b/lib/extract.c > +@@ -298,14 +298,14 @@ tar_extract_hardlink(TAR * t, char *realname) > + 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 *realname) > + > + #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()"); > +diff --git a/lib/internal.h b/lib/internal.h > +index da7be7f..f05ca4f 100644 > +--- a/lib/internal.h > ++++ b/lib/internal.h > +@@ -21,3 +21,4 @@ > + #define TLS_THREAD > + #endif > + > ++char* safer_name_suffix(char const*); > +diff --git a/lib/output.c b/lib/output.c > +index a2db929..99421bd 100644 > +--- 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'); > diff --git a/patches/libtar-1.2.20/0004-Change-th_get_size-macro-to-return-unsigned-int.patch b/patches/libtar-1.2.20/0004-Change-th_get_size-macro-to-return-unsigned-int.patch > new file mode 100644 > index 0000000..8cc3a41 > --- /dev/null > +++ b/patches/libtar-1.2.20/0004-Change-th_get_size-macro-to-return-unsigned-int.patch > @@ -0,0 +1,51 @@ > +From: Chris Frey > +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 5993cd2..b3281f7 100644 > +--- a/lib/libtar.h > ++++ b/lib/libtar.h > +@@ -183,7 +183,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) > diff --git a/patches/libtar-1.2.20/autogen.sh b/patches/libtar-1.2.20/autogen.sh > new file mode 120000 > index 0000000..9f8a4cb > --- /dev/null > +++ b/patches/libtar-1.2.20/autogen.sh > @@ -0,0 +1 @@ > +../autogen.sh > \ No newline at end of file > diff --git a/patches/libtar-1.2.20/series b/patches/libtar-1.2.20/series > new file mode 100644 > index 0000000..2af0ad9 > --- /dev/null > +++ b/patches/libtar-1.2.20/series > @@ -0,0 +1,7 @@ > +# generated by git-ptx-patches > +#tag:base --start-number 1 > +0001-decode-avoid-using-a-static-buffer-in-th_get_pathnam.patch > +0002-no_maxpathlen.patch > +0003-CVE-2013-4420.patch > +0004-Change-th_get_size-macro-to-return-unsigned-int.patch > +# 8d73710ff3b5b805b75c941056495d29 - git-ptx-patches magic > diff --git a/rules/libtar.in b/rules/libtar.in > new file mode 100644 > index 0000000..d8a800d > --- /dev/null > +++ b/rules/libtar.in > @@ -0,0 +1,11 @@ > +## SECTION=system_libraries > + > +config LIBTAR > + tristate > + prompt "libtar" > + select ZLIB > + help > + libtar is a C library for manipulating POSIX tar files. It handles > + adding and extracting files to/from a tar archive. > + > +# vim: ft=kconfig noet tw=72 > diff --git a/rules/libtar.make b/rules/libtar.make > new file mode 100644 > index 0000000..2434822 > --- /dev/null > +++ b/rules/libtar.make > @@ -0,0 +1,62 @@ > +# -*-makefile-*- > +# > +# Copyright (C) 2014 by Alexander Dahl > +# > +# See CREDITS for details about who has contributed to this project. > +# > +# For further information about the PTXdist project and license conditions > +# see the README file. > +# > + > +# > +# We provide this package > +# > +PACKAGES-$(PTXCONF_LIBTAR) += libtar > + > +# > +# Paths and names > +# > +LIBTAR_VERSION := 1.2.20 > +LIBTAR_MD5 := dcdcdf8cfbbd3df3862198b0897071b6 > +LIBTAR := libtar-$(LIBTAR_VERSION) > +LIBTAR_SUFFIX := tar.gz > +LIBTAR_URL := git://repo.or.cz/libtar.git;tag=v$(LIBTAR_VERSION) > +LIBTAR_SOURCE := $(SRCDIR)/$(LIBTAR).$(LIBTAR_SUFFIX) > +LIBTAR_DIR := $(BUILDDIR)/$(LIBTAR) > +LIBTAR_LICENSE := unknown > + > +# ---------------------------------------------------------------------------- > +# Prepare > +# ---------------------------------------------------------------------------- > + > +#LIBTAR_CONF_ENV := $(CROSS_ENV) > + > +# > +# autoconf > +# > +LIBTAR_CONF_TOOL := autoconf > +LIBTAR_CONF_OPT := $(CROSS_AUTOCONF_USR) \ > + --disable-encap \ > + --disable-epkg-install \ > + --with-zlib=$(SYSROOT) > + > +# ---------------------------------------------------------------------------- > +# Target-Install > +# ---------------------------------------------------------------------------- > + > +$(STATEDIR)/libtar.targetinstall: > + @$(call targetinfo) > + > + @$(call install_init, libtar) > + @$(call install_fixup, libtar,PRIORITY,optional) > + @$(call install_fixup, libtar,SECTION,base) > + @$(call install_fixup, libtar,AUTHOR,"Alexander Dahl ") > + @$(call install_fixup, libtar,DESCRIPTION,missing) > + > + @$(call install_lib, libtar, 0, 0, 0644, libtar) > + > + @$(call install_finish, libtar) > + > + @$(call touch) > + > +# vim: ft=make noet > -- > 1.7.10.4 > > > -- > ptxdist mailing list > ptxdist@pengutronix.de > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | -- ptxdist mailing list ptxdist@pengutronix.de