aboutsummaryrefslogtreecommitdiff
path: root/lib/xwrap.c
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2019-10-27 15:24:50 -0500
committerRob Landley <rob@landley.net>2019-10-27 15:24:50 -0500
commitb30fd4cb656d7a98c12f63fbb225db4e2cb3a776 (patch)
treeb03194ce8179682989e5d589e6937e5cbf696ea2 /lib/xwrap.c
parent01f18c4c6ee68cbd58944e21d1fe36991315a889 (diff)
downloadtoybox-b30fd4cb656d7a98c12f63fbb225db4e2cb3a776.tar.gz
Tar extract should delete files or symlinks where it's making a directory,
but --restrict checking should run on the path up to the last component before unlinking so tar can't be tricked into deleting random files off the system.
Diffstat (limited to 'lib/xwrap.c')
-rw-r--r--lib/xwrap.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/lib/xwrap.c b/lib/xwrap.c
index 1a3ef837..591c9513 100644
--- a/lib/xwrap.c
+++ b/lib/xwrap.c
@@ -525,7 +525,8 @@ void xstat(char *path, struct stat *st)
// Canonicalize path, even to file with one or more missing components at end.
// Returns allocated string for pathname or NULL if doesn't exist
-// exact = 1 file must exist, 0 dir must exist, -1 show theoretical location
+// exact = 1 file must exist, 0 dir must exist, -1 show theoretical location,
+// -2 don't resolve last file
char *xabspath(char *path, int exact)
{
struct string_list *todo, *done = 0;
@@ -570,7 +571,8 @@ char *xabspath(char *path, int exact)
}
// Is this a symlink?
- len = readlinkat(dirfd, new->str, libbuf, sizeof(libbuf));
+ if (exact == -2 && !todo) len = 0;
+ else len = readlinkat(dirfd, new->str, libbuf, sizeof(libbuf));
if (len>4095) goto error;
// Not a symlink: add to linked list, move dirfd, fail if error