summaryrefslogtreecommitdiff
path: root/gnu/packages/patches/libarchive-fix-symlink-check.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/packages/patches/libarchive-fix-symlink-check.patch')
-rw-r--r--gnu/packages/patches/libarchive-fix-symlink-check.patch60
1 files changed, 60 insertions, 0 deletions
diff --git a/gnu/packages/patches/libarchive-fix-symlink-check.patch b/gnu/packages/patches/libarchive-fix-symlink-check.patch
new file mode 100644
index 0000000000..f042c31a84
--- /dev/null
+++ b/gnu/packages/patches/libarchive-fix-symlink-check.patch
@@ -0,0 +1,60 @@
+Make sure to check for symlinks even if the pathname is very long:
+
+https://github.com/libarchive/libarchive/issues/744
+
+Patch copied from upstream repository:
+
+https://github.com/libarchive/libarchive/commit/1fa9c7bf90f0862036a99896b0501c381584451a
+
+From 1fa9c7bf90f0862036a99896b0501c381584451a Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+Date: Sun, 21 Aug 2016 17:11:45 -0700
+Subject: [PATCH] Issue #744 (part of Issue #743): Enforce sandbox with very
+ long pathnames
+
+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.
+---
+ libarchive/archive_write_disk_posix.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
+index 39ee3b6..8f0421e 100644
+--- a/libarchive/archive_write_disk_posix.c
++++ b/libarchive/archive_write_disk_posix.c
+@@ -2401,8 +2401,18 @@ check_symlinks(struct archive_write_disk *a)
+ r = lstat(a->name, &st);
+ if (r != 0) {
+ /* We've hit a dir that doesn't exist; stop now. */
+- if (errno == ENOENT)
++ if (errno == ENOENT) {
+ break;
++ } else {
++ /* Note: This effectively disables deep directory
++ * support when security checks are enabled.
++ * Otherwise, very long pathnames that trigger
++ * an error here could evade the sandbox.
++ * TODO: We could do better, but it would probably
++ * require merging the symlink checks with the
++ * deep-directory editing. */
++ return (ARCHIVE_FAILED);
++ }
+ } else if (S_ISLNK(st.st_mode)) {
+ if (c == '\0') {
+ /*