Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP4:Update
libarchive.26953
1566.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 1566.patch of Package libarchive.26953
commit 8a1bd5c18e896f0411a991240ce0d772bb02c840 Author: Martin Matuska <martin@matuska.org> Date: Fri Aug 27 10:56:28 2021 +0200 Fix following symlinks when processing the fixup list The previous fix in b41daecb5 was incomplete. Fixup entries are given the original path without calling cleanup_pathname(). To make sure we don't follow a symlink, we must strip trailing slashes from the path. The fixup entries are always directories. Make sure we try to modify only directories by providing O_DIRECTORY to open() (if supported) and if it fails to check directory via lstat(). Fixes #1566 Index: libarchive-3.3.3/libarchive/archive_write_disk_posix.c =================================================================== --- libarchive-3.3.3.orig/libarchive/archive_write_disk_posix.c +++ libarchive-3.3.3/libarchive/archive_write_disk_posix.c @@ -2319,7 +2319,9 @@ _archive_write_disk_close(struct archive { struct archive_write_disk *a = (struct archive_write_disk *)_a; struct fixup_entry *next, *p; - int ret; + struct stat st; + char *c; + int fd, ret; archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, @@ -2330,34 +2332,92 @@ _archive_write_disk_close(struct archive p = sort_dir_list(a->fixup_list); while (p != NULL) { - a->pst = NULL; /* Mark stat cache as out-of-date. */ - if (p->fixup & TODO_TIMES) { - set_times(a, -1, p->mode, p->name, - p->atime, p->atime_nanos, - p->birthtime, p->birthtime_nanos, - p->mtime, p->mtime_nanos, - p->ctime, p->ctime_nanos); - } - if (p->fixup & TODO_MODE_BASE) - chmod(p->name, p->mode); - if (p->fixup & TODO_ACLS) - archive_write_disk_set_acls(&a->archive, -1, p->name, - &p->acl, p->mode); - if (p->fixup & TODO_FFLAGS) - set_fflags_platform(a, -1, p->name, - p->mode, p->fflags_set, 0); - if (p->fixup & TODO_MAC_METADATA) - set_mac_metadata(a, p->name, p->mac_metadata, - p->mac_metadata_size); - next = p->next; - archive_acl_clear(&p->acl); - free(p->mac_metadata); - free(p->name); - free(p); - p = next; - } - a->fixup_list = NULL; - return (ret); + fd = -1; + a->pst = NULL; /* Mark stat cache as out-of-date. */ + + /* We must strip trailing slashes from the path to avoid + dereferencing symbolic links to directories */ + c = p->name; + while (*c != '\0') + c++; + while (c != p->name && *(c - 1) == '/') { + c--; + *c = '\0'; + } + + if (p->fixup == 0) + goto skip_fixup_entry; + else { + fd = open(p->name, O_BINARY | O_NOFOLLOW | O_RDONLY +#if defined(O_DIRECTORY) + | O_DIRECTORY +#endif + | O_CLOEXEC); + /* + ` * If we don't support O_DIRECTORY, + * or open() has failed, we must stat() + * to verify that we are opening a directory + */ +#if defined(O_DIRECTORY) + if (fd == -1) { + if (lstat(p->name, &st) != 0 || + !S_ISDIR(st.st_mode)) { + goto skip_fixup_entry; + } + } +#else +#if HAVE_FSTAT + if (fd > 0 && ( + fstat(fd, &st) != 0 || !S_ISDIR(st.st_mode))) { + goto skip_fixup_entry; + } else +#endif + if (lstat(p->name, &st) != 0 || + !S_ISDIR(st.st_mode)) { + goto skip_fixup_entry; + } +#endif + } + if (p->fixup & TODO_TIMES) { + set_times(a, fd, p->mode, p->name, + p->atime, p->atime_nanos, + p->birthtime, p->birthtime_nanos, + p->mtime, p->mtime_nanos, + p->ctime, p->ctime_nanos); + } + if (p->fixup & TODO_MODE_BASE) { +#ifdef HAVE_FCHMOD + if (fd >= 0) + fchmod(fd, p->mode & 07777); + else +#endif +#ifdef HAVE_LCHMOD + lchmod(p->name, p->mode & 07777); +#else + chmod(p->name, p->mode & 07777); +#endif + } + if (p->fixup & TODO_ACLS) + archive_write_disk_set_acls(&a->archive, fd, + p->name, &p->acl, p->mode); + if (p->fixup & TODO_FFLAGS) + set_fflags_platform(a, fd, p->name, + p->mode, p->fflags_set, 0); + if (p->fixup & TODO_MAC_METADATA) + set_mac_metadata(a, p->name, p->mac_metadata, + p->mac_metadata_size); +skip_fixup_entry: + next = p->next; + archive_acl_clear(&p->acl); + free(p->mac_metadata); + free(p->name); + if (fd >= 0) + close(fd); + free(p); + p = next; + } + a->fixup_list = NULL; + return (ret); } static int
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor