diff options
Diffstat (limited to 'lib/libarchive/archive_read_extract.c')
| -rw-r--r-- | lib/libarchive/archive_read_extract.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/lib/libarchive/archive_read_extract.c b/lib/libarchive/archive_read_extract.c index 8fd3196e24b8..6726f1bbff29 100644 --- a/lib/libarchive/archive_read_extract.c +++ b/lib/libarchive/archive_read_extract.c @@ -827,14 +827,28 @@ set_perm(struct archive *a, struct archive_entry *entry, int mode, int flags) mode &= ~ S_ISGID; } + /* + * Ensure we change permissions on the object we extracted, + * and not any incidental symlink that might have gotten in + * the way. + */ + if (!S_ISLNK(archive_entry_mode(entry))) { + if (chmod(name, mode) != 0) { + archive_set_error(a, errno, "Can't set permissions"); + return (ARCHIVE_WARN); + } + } else { #ifdef HAVE_LCHMOD - if (lchmod(name, mode) != 0) { -#else - if ((archive_entry_mode(entry) & S_IFMT) != S_IFLNK && - chmod(name, mode) != 0) { + /* + * If lchmod() isn't supported, it's no big deal. + * Permissions on symlinks are actually ignored on + * most platforms. + */ + if (lchmod(name, mode) != 0) { + archive_set_error(a, errno, "Can't set permissions"); + return (ARCHIVE_WARN); + } #endif - archive_set_error(a, errno, "Can't set permissions"); - return (ARCHIVE_WARN); } if (flags & ARCHIVE_EXTRACT_ACL) { |
