-
Notifications
You must be signed in to change notification settings - Fork 772
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Very long pathnames evade symlink checks #744
Milestone
Comments
Fixed in HardenedBSD with the following commit: HardenedBSD/hardenedBSD@acc5eae |
kientzle
added a commit
that referenced
this issue
Aug 10, 2016
kientzle
added a commit
that referenced
this issue
Aug 10, 2016
kientzle
added a commit
that referenced
this issue
Aug 22, 2016
…ames Because check_symlinks is handled separately from the deep-directory support, very long pathnames cause problems. Previously, the code ignored most failures to lstat() a path component. In particular, this led to check_symlinks always passing for very long paths, which in turn provides a way to evade the symlink checks in the sandboxing code. We now fail on unrecognized lstat() failures, which plugs this hole at the cost of disabling deep directory support when the user requests sandboxing. TODO: This probably cannot be completely fixed without entirely reimplementing the deep directory support to integrate the symlink checks. I want to reimplement the deep directory hanlding someday anyway; openat() and related system calls now provide a much cleaner way to handle deep directories than the chdir approach used by this code.
Fixed in commit 1fa9c7b. This is the same fix suggested in the anonymous posting and implemented in HardenedBSD. Note that deep-directory support is no longer functional if sandboxing is enabled. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is the second of four problems mentioned in Issue #743:
{Affects}
3.2.0 (FreeBSD HEAD/ports), 3.1.2 (FreeBSD non-HEAD), possibly earlier
{Description}
When check_symlinks() fails on an lstat() call, it checks errno for only
ENOENT:
All other error conditions get a free pass. In particular, ENAMETOOLONG gets a
free pass. This is by design: The function _archive_write_disk_header() calls
edit_deep_directories() after check_symlinks() in an effort to accommodate deep
directories. Unfortunately, the interaction between the symlink checks and the
deep-directory support introduces a security vulnerability, in that the symlink
checks are effectively disabled for long pathnames.
{Demonstration}
{Defense}
The best solution is probably to excise the function edit_deep_directories()
altogether and then change check_symlinks() to return ARCHIVE_FAILED when
lstat() fails with errno other than ENOENT. It does not appear to be worth the
trouble trying to work around PATH_MAX. Incidentally, POSIX defines PATH_MAX
to include the terminating NUL, so if edit_deep_directories() is to remain, its
two strlen() checks should be fixed accordingly: < PATH_MAX and >= PATH_MAX.
The text was updated successfully, but these errors were encountered: