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 <p...@lespocky.de> --- ...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 <kdu...@redhat.com> +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 <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; + } + + +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 <unknown.aut...@example.com> +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 <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); + } +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 <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') { +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 <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; + } + +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 <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, 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 <unknown.aut...@example.com> +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 <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); + } + + +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 <cdf...@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 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 <p...@lespocky.de> +# +# 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 <p...@lespocky.de>") + @$(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