gnu: libarchive: Fix several security issues.
[jackhill/guix/guix.git] / gnu / packages / patches / libarchive-fix-symlink-check.patch
1 Make sure to check for symlinks even if the pathname is very long:
2
3 https://github.com/libarchive/libarchive/issues/744
4
5 Patch copied from upstream repository:
6
7 https://github.com/libarchive/libarchive/commit/1fa9c7bf90f0862036a99896b0501c381584451a
8
9 From 1fa9c7bf90f0862036a99896b0501c381584451a Mon Sep 17 00:00:00 2001
10 From: Tim Kientzle <kientzle@acm.org>
11 Date: Sun, 21 Aug 2016 17:11:45 -0700
12 Subject: [PATCH] Issue #744 (part of Issue #743): Enforce sandbox with very
13 long pathnames
14
15 Because check_symlinks is handled separately from the deep-directory
16 support, very long pathnames cause problems. Previously, the code
17 ignored most failures to lstat() a path component. In particular,
18 this led to check_symlinks always passing for very long paths, which
19 in turn provides a way to evade the symlink checks in the sandboxing
20 code.
21
22 We now fail on unrecognized lstat() failures, which plugs this
23 hole at the cost of disabling deep directory support when the
24 user requests sandboxing.
25
26 TODO: This probably cannot be completely fixed without
27 entirely reimplementing the deep directory support to
28 integrate the symlink checks. I want to reimplement the
29 deep directory hanlding someday anyway; openat() and
30 related system calls now provide a much cleaner way to
31 handle deep directories than the chdir approach used by this
32 code.
33 ---
34 libarchive/archive_write_disk_posix.c | 12 +++++++++++-
35 1 file changed, 11 insertions(+), 1 deletion(-)
36
37 diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
38 index 39ee3b6..8f0421e 100644
39 --- a/libarchive/archive_write_disk_posix.c
40 +++ b/libarchive/archive_write_disk_posix.c
41 @@ -2401,8 +2401,18 @@ check_symlinks(struct archive_write_disk *a)
42 r = lstat(a->name, &st);
43 if (r != 0) {
44 /* We've hit a dir that doesn't exist; stop now. */
45 - if (errno == ENOENT)
46 + if (errno == ENOENT) {
47 break;
48 + } else {
49 + /* Note: This effectively disables deep directory
50 + * support when security checks are enabled.
51 + * Otherwise, very long pathnames that trigger
52 + * an error here could evade the sandbox.
53 + * TODO: We could do better, but it would probably
54 + * require merging the symlink checks with the
55 + * deep-directory editing. */
56 + return (ARCHIVE_FAILED);
57 + }
58 } else if (S_ISLNK(st.st_mode)) {
59 if (c == '\0') {
60 /*