?revision_form?Rev ?revision_input??revision_submit??revision_endform?
Blame |
Last modification |
View Log
| RSS feed
Description: Fix memory leaks related to th_get_pathname()
Author: James Morrison <phython@debian.org>
Author: Martin Gadbois <martin.gadbois@colubris.com>
Author: Magnus Holmgren <holmgren@debian.org>
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/libtar/+bug/41804
--- a/lib/wrapper.c
+++ b/lib/wrapper.c
@@ -18,6 +18,7 @@
#include <errno.h>
#ifdef STDC_HEADERS
+# include <stdlib.h>
# include <string.h>
#endif
@@ -35,7 +36,10 @@ tar_extract_glob(TAR *t, char *globname,
if (fnmatch(globname, filename, FNM_PATHNAME | FNM_PERIOD))
{
if (TH_ISREG(t) && tar_skip_regfile(t))
+ {
+ free(filename);
return -1;
+ }
continue;
}
if (t->options & TAR_VERBOSE)
@@ -45,7 +49,11 @@ tar_extract_glob(TAR *t, char *globname,
else
strlcpy(buf, filename, sizeof(buf));
if (tar_extract_file(t, filename) != 0)
+ {
+ free(filename);
return -1;
+ }
+ free(filename);
}
return (i == 1 ? 0 : -1);
@@ -76,12 +84,17 @@ tar_extract_all(TAR *t, char *prefix)
snprintf(buf, sizeof(buf), "%s/%s", prefix, filename);
else
strlcpy(buf, filename, sizeof(buf));
+ free(filename);
#ifdef DEBUG
printf(" tar_extract_all(): calling tar_extract_file(t, "
"\"%s\")\n", buf);
#endif
if (tar_extract_file(t, buf) != 0)
+ {
+ free(filename);
return -1;
+ }
+ free(filename);
}
return (i == 1 ? 0 : -1);
--- a/lib/extract.c
+++ b/lib/extract.c
@@ -21,6 +21,7 @@
#ifdef STDC_HEADERS
# include <stdlib.h>
+# include <string.h>
#endif
#ifdef HAVE_UNISTD_H
@@ -43,9 +44,10 @@ tar_set_file_perms(TAR *t, char *realnam
uid_t uid;
gid_t gid;
struct utimbuf ut;
- char *filename;
+ char *filename,*pathname;
- filename = (realname ? realname : th_get_pathname(t));
+ pathname = th_get_pathname(t);
+ filename = (realname ? realname : pathname);
mode = th_get_mode(t);
uid = th_get_uid(t);
gid = th_get_gid(t);
@@ -68,6 +70,7 @@ tar_set_file_perms(TAR *t, char *realnam
filename, uid, gid, strerror(errno));
# endif
#endif /* HAVE_LCHOWN */
+ free(pathname);
return -1;
}
@@ -77,6 +80,7 @@ tar_set_file_perms(TAR *t, char *realnam
#ifdef DEBUG
perror("utime()");
#endif
+ free(pathname);
return -1;
}
@@ -86,9 +90,10 @@ tar_set_file_perms(TAR *t, char *realnam
#ifdef DEBUG
perror("chmod()");
#endif
+ free(pathname);
return -1;
}
-
+ free(pathname);
return 0;
}
@@ -99,6 +104,7 @@ tar_extract_file(TAR *t, char *realname)
{
int i;
linkname_t *lnp;
+ char *pathname;
if (t->options & TAR_NOOVERWRITE)
{
@@ -140,12 +146,14 @@ tar_extract_file(TAR *t, char *realname)
lnp = (linkname_t *)calloc(1, sizeof(linkname_t));
if (lnp == NULL)
return -1;
- strlcpy(lnp->ln_save, th_get_pathname(t), sizeof(lnp->ln_save));
+ pathname = th_get_pathname(t);
+ strlcpy(lnp->ln_save, pathname, sizeof(lnp->ln_save));
strlcpy(lnp->ln_real, realname, sizeof(lnp->ln_real));
#ifdef DEBUG
printf("tar_extract_file(): calling libtar_hash_add(): key=\"%s\", "
- "value=\"%s\"\n", th_get_pathname(t), realname);
+ "value=\"%s\"\n", pathname, realname);
#endif
+ free(pathname);
if (libtar_hash_add(t->h, lnp) != 0)
return -1;
@@ -164,7 +172,7 @@ tar_extract_regfile(TAR *t, char *realna
int fdout;
int i, k;
char buf[T_BLOCKSIZE];
- char *filename;
+ char *filename,*pathname;
#ifdef DEBUG
printf("==> tar_extract_regfile(t=0x%lx, realname=\"%s\")\n", t,
@@ -176,15 +184,18 @@ tar_extract_regfile(TAR *t, char *realna
errno = EINVAL;
return -1;
}
-
- filename = (realname ? realname : th_get_pathname(t));
+ pathname = th_get_pathname(t);
+ filename = (realname ? realname : pathname);
mode = th_get_mode(t);
size = th_get_size(t);
uid = th_get_uid(t);
gid = th_get_gid(t);
if (mkdirhier(dirname(filename)) == -1)
+ {
+ free(pathname);
return -1;
+ }
#ifdef DEBUG
printf(" ==> extracting: %s (mode %04o, uid %d, gid %d, %d bytes)\n",
@@ -200,6 +211,7 @@ tar_extract_regfile(TAR *t, char *realna
#ifdef DEBUG
perror("open()");
#endif
+ free(pathname);
return -1;
}
@@ -231,23 +243,30 @@ tar_extract_regfile(TAR *t, char *realna
{
if (k != -1)
errno = EINVAL;
+ free(pathname);
return -1;
}
/* write block to output file */
if (write(fdout, buf,
((i > T_BLOCKSIZE) ? T_BLOCKSIZE : i)) == -1)
+ {
+ free(pathname);
return -1;
+ }
}
/* close output file */
if (close(fdout) == -1)
+ {
+ free(pathname);
return -1;
+ }
#ifdef DEBUG
printf("### done extracting %s\n", filename);
#endif
-
+ free(pathname);
return 0;
}
@@ -286,7 +305,7 @@ tar_skip_regfile(TAR *t)
int
tar_extract_hardlink(TAR * t, char *realname)
{
- char *filename;
+ char *filename,*pathname;
char *linktgt = NULL;
linkname_t *lnp;
libtar_hashptr_t hp;
@@ -296,10 +315,14 @@ tar_extract_hardlink(TAR * t, char *real
errno = EINVAL;
return -1;
}
-
- filename = (realname ? realname : th_get_pathname(t));
+
+ pathname = th_get_pathname(t);
+ filename = (realname ? realname : pathname);
if (mkdirhier(dirname(filename)) == -1)
+ {
+ free(pathname);
return -1;
+ }
libtar_hashptr_reset(&hp);
if (libtar_hash_getkey(t->h, &hp, th_get_linkname(t),
(libtar_matchfunc_t)libtar_str_match) != 0)
@@ -318,9 +341,10 @@ tar_extract_hardlink(TAR * t, char *real
#ifdef DEBUG
perror("link()");
#endif
+ free(pathname);
return -1;
}
-
+ free(pathname);
return 0;
}
@@ -329,7 +353,7 @@ tar_extract_hardlink(TAR * t, char *real
int
tar_extract_symlink(TAR *t, char *realname)
{
- char *filename;
+ char *filename,*pathname;
if (!TH_ISSYM(t))
{
@@ -337,12 +361,19 @@ tar_extract_symlink(TAR *t, char *realna
return -1;
}
- filename = (realname ? realname : th_get_pathname(t));
+ pathname = th_get_pathname(t);
+ filename = (realname ? realname : pathname);
if (mkdirhier(dirname(filename)) == -1)
+ {
+ free(pathname);
return -1;
+ }
if (unlink(filename) == -1 && errno != ENOENT)
+ {
+ free(pathname);
return -1;
+ }
#ifdef DEBUG
printf(" ==> extracting: %s (symlink to %s)\n",
@@ -353,9 +384,10 @@ tar_extract_symlink(TAR *t, char *realna
#ifdef DEBUG
perror("symlink()");
#endif
+ free(pathname);
return -1;
}
-
+ free(pathname);
return 0;
}
@@ -366,7 +398,7 @@ tar_extract_chardev(TAR *t, char *realna
{
mode_t mode;
unsigned long devmaj, devmin;
- char *filename;
+ char *filename,*pathname;
if (!TH_ISCHR(t))
{
@@ -374,13 +406,17 @@ tar_extract_chardev(TAR *t, char *realna
return -1;
}
- filename = (realname ? realname : th_get_pathname(t));
+ pathname = th_get_pathname(t);
+ filename = (realname ? realname : pathname);
mode = th_get_mode(t);
devmaj = th_get_devmajor(t);
devmin = th_get_devminor(t);
if (mkdirhier(dirname(filename)) == -1)
+ {
+ free(pathname);
return -1;
+ }
#ifdef DEBUG
printf(" ==> extracting: %s (character device %ld,%ld)\n",
@@ -392,9 +428,10 @@ tar_extract_chardev(TAR *t, char *realna
#ifdef DEBUG
perror("mknod()");
#endif
+ free(pathname);
return -1;
}
-
+ free(pathname);
return 0;
}
@@ -405,7 +442,7 @@ tar_extract_blockdev(TAR *t, char *realn
{
mode_t mode;
unsigned long devmaj, devmin;
- char *filename;
+ char *filename,*pathname;
if (!TH_ISBLK(t))
{
@@ -413,13 +450,17 @@ tar_extract_blockdev(TAR *t, char *realn
return -1;
}
- filename = (realname ? realname : th_get_pathname(t));
+ pathname = th_get_pathname(t);
+ filename = (realname ? realname : pathname);
mode = th_get_mode(t);
devmaj = th_get_devmajor(t);
devmin = th_get_devminor(t);
if (mkdirhier(dirname(filename)) == -1)
+ {
+ free(pathname);
return -1;
+ }
#ifdef DEBUG
printf(" ==> extracting: %s (block device %ld,%ld)\n",
@@ -431,9 +472,10 @@ tar_extract_blockdev(TAR *t, char *realn
#ifdef DEBUG
perror("mknod()");
#endif
+ free(pathname);
return -1;
}
-
+ free(pathname);
return 0;
}
@@ -443,7 +485,7 @@ int
tar_extract_dir(TAR *t, char *realname)
{
mode_t mode;
- char *filename;
+ char *filename,*pathname;
if (!TH_ISDIR(t))
{
@@ -451,11 +493,15 @@ tar_extract_dir(TAR *t, char *realname)
return -1;
}
- filename = (realname ? realname : th_get_pathname(t));
+ pathname = th_get_pathname(t);
+ filename = (realname ? realname : pathname);
mode = th_get_mode(t);
if (mkdirhier(dirname(filename)) == -1)
+ {
+ free(pathname);
return -1;
+ }
#ifdef DEBUG
printf(" ==> extracting: %s (mode %04o, directory)\n", filename,
@@ -470,6 +516,7 @@ tar_extract_dir(TAR *t, char *realname)
#ifdef DEBUG
perror("chmod()");
#endif
+ free(pathname);
return -1;
}
else
@@ -477,6 +524,7 @@ tar_extract_dir(TAR *t, char *realname)
#ifdef DEBUG
puts(" *** using existing directory");
#endif
+ free(pathname);
return 1;
}
}
@@ -485,10 +533,11 @@ tar_extract_dir(TAR *t, char *realname)
#ifdef DEBUG
perror("mkdir()");
#endif
+ free(pathname);
return -1;
}
}
-
+ free(pathname);
return 0;
}
@@ -498,7 +547,7 @@ int
tar_extract_fifo(TAR *t, char *realname)
{
mode_t mode;
- char *filename;
+ char *filename,*pathname;
if (!TH_ISFIFO(t))
{
@@ -506,11 +555,15 @@ tar_extract_fifo(TAR *t, char *realname)
return -1;
}
- filename = (realname ? realname : th_get_pathname(t));
+ pathname = th_get_pathname(t);
+ filename = (realname ? realname : pathname);
mode = th_get_mode(t);
if (mkdirhier(dirname(filename)) == -1)
+ {
+ free(pathname);
return -1;
+ }
#ifdef DEBUG
printf(" ==> extracting: %s (fifo)\n", filename);
@@ -520,9 +573,11 @@ tar_extract_fifo(TAR *t, char *realname)
#ifdef DEBUG
perror("mkfifo()");
#endif
+ free(pathname);
return -1;
}
+ free(pathname);
return 0;
}
--- a/lib/output.c
+++ b/lib/output.c
@@ -20,6 +20,7 @@
#include <sys/param.h>
#ifdef STDC_HEADERS
+# include <stdlib.h>
# include <string.h>
#endif
@@ -71,6 +72,7 @@ th_print_long_ls(TAR *t)
char groupname[_POSIX_LOGIN_NAME_MAX];
time_t mtime;
struct tm *mtm;
+ char *pathname;
#ifdef HAVE_STRFTIME
char timebuf[18];
@@ -114,7 +116,9 @@ th_print_long_ls(TAR *t)
mtm->tm_mday, mtm->tm_hour, mtm->tm_min, mtm->tm_year + 1900);
#endif
- printf(" %s", th_get_pathname(t));
+ pathname = th_get_pathname(t);
+ printf(" %s", pathname);
+ free(pathname);
if (TH_ISSYM(t) || TH_ISLNK(t))
{
--- a/lib/decode.c
+++ b/lib/decode.c
@@ -29,7 +29,7 @@ th_get_pathname(TAR *t)
char filename[MAXPATHLEN];
if (t->th_buf.gnu_longname)
- return t->th_buf.gnu_longname;
+ return strdup(t->th_buf.gnu_longname);
if (t->th_buf.prefix[0] != '\0')
{