tar: postpone creation of symlinks with "suspicious" targets. Closes 8411
function old new delta data_extract_all 968 1038 +70 tar_main 952 986 +34 scan_tree 258 262 +4 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 108/0) Total: 108 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
@@ -128,10 +128,11 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
|
||||
res = link(hard_link, dst_name);
|
||||
if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
|
||||
/* shared message */
|
||||
bb_perror_msg("can't create %slink "
|
||||
"%s to %s", "hard",
|
||||
bb_perror_msg("can't create %slink '%s' to '%s'",
|
||||
"hard",
|
||||
dst_name,
|
||||
hard_link);
|
||||
hard_link
|
||||
);
|
||||
}
|
||||
/* Hardlinks have no separate mode/ownership, skip chown/chmod */
|
||||
goto ret;
|
||||
@@ -178,15 +179,44 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
|
||||
case S_IFLNK:
|
||||
/* Symlink */
|
||||
//TODO: what if file_header->link_target == NULL (say, corrupted tarball?)
|
||||
|
||||
/* To avoid a directory traversal attack via symlinks,
|
||||
* for certain link targets postpone creation of symlinks.
|
||||
*
|
||||
* For example, consider a .tar created via:
|
||||
* $ tar cvf bug.tar anything.txt
|
||||
* $ ln -s /tmp symlink
|
||||
* $ tar --append -f bug.tar symlink
|
||||
* $ rm symlink
|
||||
* $ mkdir symlink
|
||||
* $ tar --append -f bug.tar symlink/evil.py
|
||||
*
|
||||
* This will result in an archive that contains:
|
||||
* $ tar --list -f bug.tar
|
||||
* anything.txt
|
||||
* symlink [-> /tmp]
|
||||
* symlink/evil.py
|
||||
*
|
||||
* Untarring bug.tar would otherwise place evil.py in '/tmp'.
|
||||
*/
|
||||
if (file_header->link_target[0] == '/'
|
||||
|| strstr(file_header->link_target, "..")
|
||||
) {
|
||||
llist_add_to(&archive_handle->symlink_placeholders,
|
||||
xasprintf("%s%c%s", file_header->name, '\0', file_header->link_target)
|
||||
);
|
||||
break;
|
||||
}
|
||||
res = symlink(file_header->link_target, dst_name);
|
||||
if (res != 0
|
||||
&& !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
|
||||
) {
|
||||
/* shared message */
|
||||
bb_perror_msg("can't create %slink "
|
||||
"%s to %s", "sym",
|
||||
bb_perror_msg("can't create %slink '%s' to '%s'",
|
||||
"sym",
|
||||
dst_name,
|
||||
file_header->link_target);
|
||||
file_header->link_target
|
||||
);
|
||||
}
|
||||
break;
|
||||
case S_IFSOCK:
|
||||
|
Reference in New Issue
Block a user