diff options
author | Ron Yorston <rmy@pobox.com> | 2017-07-29 09:55:08 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2017-07-29 09:55:08 +0100 |
commit | 86d60bb0ceb277e500a8daabd995bc713bbdadc9 (patch) | |
tree | 3e439f92d5a3fec2546d526579cc85e98f066e40 /archival/libarchive | |
parent | b30c60a9786a1608211a96755996bd6c02951a27 (diff) | |
parent | 69be994de69d794f038f10a3e7a67519b2006581 (diff) | |
download | busybox-w32-86d60bb0ceb277e500a8daabd995bc713bbdadc9.tar.gz busybox-w32-86d60bb0ceb277e500a8daabd995bc713bbdadc9.tar.bz2 busybox-w32-86d60bb0ceb277e500a8daabd995bc713bbdadc9.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'archival/libarchive')
-rw-r--r-- | archival/libarchive/data_extract_all.c | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c index 1830ffb8d..1ce927c2f 100644 --- a/archival/libarchive/data_extract_all.c +++ b/archival/libarchive/data_extract_all.c | |||
@@ -128,10 +128,11 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
128 | res = link(hard_link, dst_name); | 128 | res = link(hard_link, dst_name); |
129 | if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) { | 129 | if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) { |
130 | /* shared message */ | 130 | /* shared message */ |
131 | bb_perror_msg("can't create %slink " | 131 | bb_perror_msg("can't create %slink '%s' to '%s'", |
132 | "%s to %s", "hard", | 132 | "hard", |
133 | dst_name, | 133 | dst_name, |
134 | hard_link); | 134 | hard_link |
135 | ); | ||
135 | } | 136 | } |
136 | /* Hardlinks have no separate mode/ownership, skip chown/chmod */ | 137 | /* Hardlinks have no separate mode/ownership, skip chown/chmod */ |
137 | goto ret; | 138 | goto ret; |
@@ -178,15 +179,44 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
178 | case S_IFLNK: | 179 | case S_IFLNK: |
179 | /* Symlink */ | 180 | /* Symlink */ |
180 | //TODO: what if file_header->link_target == NULL (say, corrupted tarball?) | 181 | //TODO: what if file_header->link_target == NULL (say, corrupted tarball?) |
182 | |||
183 | /* To avoid a directory traversal attack via symlinks, | ||
184 | * for certain link targets postpone creation of symlinks. | ||
185 | * | ||
186 | * For example, consider a .tar created via: | ||
187 | * $ tar cvf bug.tar anything.txt | ||
188 | * $ ln -s /tmp symlink | ||
189 | * $ tar --append -f bug.tar symlink | ||
190 | * $ rm symlink | ||
191 | * $ mkdir symlink | ||
192 | * $ tar --append -f bug.tar symlink/evil.py | ||
193 | * | ||
194 | * This will result in an archive that contains: | ||
195 | * $ tar --list -f bug.tar | ||
196 | * anything.txt | ||
197 | * symlink [-> /tmp] | ||
198 | * symlink/evil.py | ||
199 | * | ||
200 | * Untarring bug.tar would otherwise place evil.py in '/tmp'. | ||
201 | */ | ||
202 | if (file_header->link_target[0] == '/' | ||
203 | || strstr(file_header->link_target, "..") | ||
204 | ) { | ||
205 | llist_add_to(&archive_handle->symlink_placeholders, | ||
206 | xasprintf("%s%c%s", file_header->name, '\0', file_header->link_target) | ||
207 | ); | ||
208 | break; | ||
209 | } | ||
181 | res = symlink(file_header->link_target, dst_name); | 210 | res = symlink(file_header->link_target, dst_name); |
182 | if (res != 0 | 211 | if (res != 0 |
183 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | 212 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) |
184 | ) { | 213 | ) { |
185 | /* shared message */ | 214 | /* shared message */ |
186 | bb_perror_msg("can't create %slink " | 215 | bb_perror_msg("can't create %slink '%s' to '%s'", |
187 | "%s to %s", "sym", | 216 | "sym", |
188 | dst_name, | 217 | dst_name, |
189 | file_header->link_target); | 218 | file_header->link_target |
219 | ); | ||
190 | } | 220 | } |
191 | break; | 221 | break; |
192 | case S_IFSOCK: | 222 | case S_IFSOCK: |