diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2015-03-09 04:23:30 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2015-03-09 04:23:30 +0000 |
commit | b6b3f50a9ed5827544d33f45b4ea05a0c5df9e34 (patch) | |
tree | b683fe8f50a6acb13f707f6b0670867d3a56dc9a /bin/pax/pat_rep.c | |
parent | a86810706f7590c416472a4fe7763693a8532531 (diff) |
Unrevert post-unlock:
* Prevent an archive from esacaping the current directory by itself:
when extracting a symlink whose value is absolute or contains ".."
components, just create a zero-length normal file (with additional
tracking of the mode and hardlinks to the symlink) until everything
else is extracted, then go back and replace it with the requested
link (if it's still that zero-length placeholder).
* For tar without -P, if a path in the archive has any ".." components
then strip everything up to and including the last of them (if
it ends in ".." then it becomes ".")
This mostly follows GNU tar's behavior, except for 'tar tf' and
'tar xvf' we report the modified path that would be/was actually
created instead of the raw path from the archive
Above two fixes prompted by a report from Daniel Cegielka
(daniel.cegielka (at) gmail.com)
* For directories whose times or mode will be fixed up in the
clean-up pass, record their dev+ino and then use
open(O_DIRECTORY)+fstat() to verify that we're updating the correct
directory before using futimens() and fchmod().
* Correct buffer overflow in handling of pax extension headers,
caught by the memcpy() overlap check.
previously ok millert@ deraadt@
Diffstat (limited to 'bin/pax/pat_rep.c')
-rw-r--r-- | bin/pax/pat_rep.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/bin/pax/pat_rep.c b/bin/pax/pat_rep.c index 55def38fa9c..92696b38dc8 100644 --- a/bin/pax/pat_rep.c +++ b/bin/pax/pat_rep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pat_rep.c,v 1.37 2015/02/21 22:48:23 guenther Exp $ */ +/* $OpenBSD: pat_rep.c,v 1.38 2015/03/09 04:23:29 guenther Exp $ */ /* $NetBSD: pat_rep.c,v 1.4 1995/03/21 09:07:33 cgd Exp $ */ /*- @@ -583,6 +583,25 @@ range_match(char *pattern, int test) } /* + * has_dotdot() + * Returns true iff the supplied path contains a ".." component. + */ + +int +has_dotdot(const char *path) +{ + const char *p = path; + + while ((p = strstr(p, "..")) != NULL) { + if ((p == path || p[-1] == '/') && + (p[2] == '/' || p[2] == '\0')) + return (1); + p += 2; + } + return (0); +} + +/* * mod_name() * modify a selected file name. first attempt to apply replacement string * expressions, then apply interactive file rename. We apply replacement @@ -632,6 +651,30 @@ mod_name(ARCHD *arcn) paxwarn(0, "Removing leading / from absolute path names in the archive"); } } + if (rmleadslash) { + const char *last = NULL; + const char *p = arcn->name; + + while ((p = strstr(p, "..")) != NULL) { + if ((p == arcn->name || p[-1] == '/') && + (p[2] == '/' || p[2] == '\0')) + last = p + 2; + p += 2; + } + if (last != NULL) { + last++; + paxwarn(1, "Removing leading \"%.*s\"", + (int)(last - arcn->name), arcn->name); + arcn->nlen = strlen(last); + if (arcn->nlen > 0) + memmove(arcn->name, last, arcn->nlen + 1); + else { + arcn->name[0] = '.'; + arcn->name[1] = '\0'; + arcn->nlen = 1; + } + } + } /* * IMPORTANT: We have a problem. what do we do with symlinks? |