int pass = 0;
mode_t file_mode;
struct stat sb;
- char target[MAXPATHLEN];
+ char *target = NULL;
char *nm = arcn->name;
int len;
if (strcmp(NM_TAR, argv0) == 0 && Lflag) {
while (lstat(nm, &sb) == 0 &&
S_ISLNK(sb.st_mode)) {
+ target = malloc(sb.st_size + 1);
+ if (target == NULL) {
+ oerrno = ENOMEM;
+ syswarn(1, oerrno,
+ "Insufficient memory");
+ return(-1);
+ }
len = readlink(nm, target,
- sizeof target - 1);
+ sb.st_size + 1);
if (len == -1) {
syswarn(0, errno,
"cannot follow symlink %s in chain for %s",
res = -1;
goto badlink;
}
+ if (len > sb.st_size) {
+ syswarn(0, errno,
+ "symlink %s increased in size between lstat() and readlink() for %s",
+ nm, arcn->name);
+
+ res = -1;
+ goto badlink;
+ }
target[len] = '\0';
nm = target;
}
paxwarn(0,
"%s skipped. Sockets cannot be copied or extracted",
nm);
+ free(target);
return(-1);
case PAX_SLK:
res = symlink(arcn->ln_name, nm);
*/
paxwarn(0, "%s has an unknown file type, skipping",
nm);
+ free(target);
return(-1);
}
* we failed to make the node
*/
oerrno = errno;
- if ((ign = unlnk_exist(nm, arcn->type)) < 0)
+ if ((ign = unlnk_exist(nm, arcn->type)) < 0) {
+ free(target);
return(-1);
+ }
if (++pass <= 1)
continue;
if (nodirs || chk_path(nm,arcn->sb.st_uid,arcn->sb.st_gid) < 0) {
syswarn(1, oerrno, "Could not create: %s", nm);
+ free(target);
return(-1);
}
}
/*
* symlinks are done now.
*/
- if (arcn->type == PAX_SLK)
+ if (arcn->type == PAX_SLK) {
+ free(target);
return(0);
+ }
/*
* IMPORTANT SECURITY NOTE:
if (patime || pmtime)
set_ftime(nm, arcn->sb.st_mtime, arcn->sb.st_atime, 0);
+ free(target);
return(0);
}