Gentoo Archives: gentoo-commits

From: Mike Frysinger <vapier@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/sandbox:master commit in: libsandbox/, tests/
Date: Sun, 20 Sep 2015 08:15:41
Message-Id: 1442733817.93d401570d4e54f732c0f821cdbb5ba2e1dee0f3.vapier@gentoo
1 commit: 93d401570d4e54f732c0f821cdbb5ba2e1dee0f3
2 Author: Mike Frysinger <vapier <AT> gentoo <DOT> org>
3 AuthorDate: Sun Sep 20 07:23:37 2015 +0000
4 Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org>
5 CommitDate: Sun Sep 20 07:23:37 2015 +0000
6 URL: https://gitweb.gentoo.org/proj/sandbox.git/commit/?id=93d40157
7
8 libsandbox: fix handling of dangling symlinks
9
10 Make sure we properly check the target of symlinks even when the target
11 does not exist. This caused problems in two ways:
12 (1) It allowed code to bypass checks by writing through a symlink that
13 was in a good location but pointed to a bad (non-existent) location.
14 (2) It caused code to be wrongly rejected when it tried writing to a
15 symlink in a bad location but pointed to a good location.
16
17 In order to get this behavior, we need to use the new gnulib helpers
18 added in the previous commit. They include functions which can look
19 up the targets of symlinks even when the final path doesn't exist.
20
21 URL: https://bugs.gentoo.org/540828
22 Reported-by: Rick Farina <zerochaos <AT> gentoo.org>
23 Signed-off-by: Mike Frysinger <vapier <AT> gentoo.org>
24
25 libsandbox/libsandbox.c | 23 ++++++++++++++++++-----
26 tests/script-11.sh | 19 +++++++++++++++++++
27 tests/script-12.sh | 25 +++++++++++++++++++++++++
28 tests/script.at | 2 ++
29 4 files changed, 64 insertions(+), 5 deletions(-)
30
31 diff --git a/libsandbox/libsandbox.c b/libsandbox/libsandbox.c
32 index 3bd3794..57be731 100644
33 --- a/libsandbox/libsandbox.c
34 +++ b/libsandbox/libsandbox.c
35 @@ -240,7 +240,12 @@ static char *resolve_path(const char *path, int follow_link)
36 else
37 ret = realpath(path, filtered_path);
38
39 - /* Maybe we failed because of funky anonymous fd symlinks.
40 + /* Handle broken symlinks. This can come up for a variety of reasons,
41 + * but we need to make sure that we resolve the path all the way to the
42 + * final target, and not just where the current link happens to start.
43 + * Latest discussion is in #540828.
44 + *
45 + * Maybe we failed because of funky anonymous fd symlinks.
46 * You can see this by doing something like:
47 * $ echo | ls -l /proc/self/fd/
48 * ....... 0 -> pipe:[9422999]
49 @@ -248,11 +253,19 @@ static char *resolve_path(const char *path, int follow_link)
50 * actual file paths for us to check against. #288863
51 * Don't look for any particular string as these are dynamic
52 * according to the kernel. You can see pipe:, socket:, etc...
53 + *
54 + * Maybe we failed because it's a symlink to a path in /proc/ that
55 + * is a symlink to a path that longer exists -- readlink will set
56 + * ENOENT even in that case and the file ends in (deleted). This
57 + * can come up in cases like:
58 + * /dev/stderr -> fd/2 -> /proc/self/fd/2 -> /removed/file (deleted)
59 */
60 - if (!ret && !strncmp(filtered_path, "/proc/", 6)) {
61 - char *base = strrchr(filtered_path, '/');
62 - if (base && strchr(base, ':'))
63 - ret = filtered_path;
64 + if (!ret && errno == ENOENT) {
65 + ret = canonicalize_filename_mode(path, CAN_ALL_BUT_LAST);
66 + if (ret) {
67 + free(filtered_path);
68 + filtered_path = ret;
69 + }
70 }
71
72 if (!ret) {
73
74 diff --git a/tests/script-11.sh b/tests/script-11.sh
75 new file mode 100755
76 index 0000000..da9bbbf
77 --- /dev/null
78 +++ b/tests/script-11.sh
79 @@ -0,0 +1,19 @@
80 +#!/bin/sh
81 +# handle targets of dangling symlinks correctly #540828
82 +[ "${at_xfail}" = "yes" ] && exit 77 # see script-0
83 +
84 +# this should fail
85 +mkdir subdir
86 +ln -s subdir/target symlink
87 +
88 +adddeny "${PWD}/subdir"
89 +
90 +echo blah >symlink
91 +# we should not be able to write through the symlink
92 +if [ $? -eq 0 ] ; then
93 + exit 1
94 +fi
95 +
96 +test -s "${SANDBOX_LOG}"
97 +
98 +exit $?
99
100 diff --git a/tests/script-12.sh b/tests/script-12.sh
101 new file mode 100755
102 index 0000000..a80108b
103 --- /dev/null
104 +++ b/tests/script-12.sh
105 @@ -0,0 +1,25 @@
106 +#!/bin/sh
107 +# handle targets of dangling symlinks correctly #540828
108 +[ "${at_xfail}" = "yes" ] && exit 77 # see script-0
109 +
110 +# this should pass
111 +mkdir subdir
112 +ln -s subdir/target symlink
113 +
114 +# make sure the log is in a writable location
115 +SANDBOX_LOG="${PWD}/subdir/log"
116 +
117 +(
118 +# This clobbers all existing writable paths for this one write.
119 +SANDBOX_WRITE="${PWD}/subdir"
120 +echo pass >symlink
121 +)
122 +# we should be able to write through the symlink
123 +if [ $? -ne 0 ] ; then
124 + exit 1
125 +fi
126 +
127 +# and not gotten a sandbox violation
128 +test ! -s "${SANDBOX_LOG}"
129 +
130 +exit $?
131
132 diff --git a/tests/script.at b/tests/script.at
133 index 93e370a..f07a8f1 100644
134 --- a/tests/script.at
135 +++ b/tests/script.at
136 @@ -8,3 +8,5 @@ SB_CHECK(7)
137 SB_CHECK(8)
138 SB_CHECK(9, [wait errpipe... done OK!])
139 SB_CHECK(10)
140 +SB_CHECK(11)
141 +SB_CHECK(12)