aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libsandbox/libsandbox.c22
-rw-r--r--tests/script-14.sh20
-rw-r--r--tests/script.at1
3 files changed, 40 insertions, 3 deletions
diff --git a/libsandbox/libsandbox.c b/libsandbox/libsandbox.c
index e164dcf..962690e 100644
--- a/libsandbox/libsandbox.c
+++ b/libsandbox/libsandbox.c
@@ -632,9 +632,25 @@ static int check_prefixes(char **prefixes, int num_prefixes, const char *path)
return 0;
size_t i;
- for (i = 0; i < num_prefixes; ++i)
- if (prefixes[i] && !strncmp(path, prefixes[i], strlen(prefixes[i])))
- return 1;
+ for (i = 0; i < num_prefixes; ++i) {
+ if (unlikely(!prefixes[i]))
+ continue;
+
+ size_t prefix_len = strlen(prefixes[i]);
+ /* Start with a regular prefix match for speed */
+ if (strncmp(path, prefixes[i], prefix_len))
+ continue;
+
+ /* Now, if prefix did not end with a slash, we need to make sure
+ * we are not matching in the middle of a filename. So check
+ * whether the match is followed by a slash, or NUL.
+ */
+ if (prefixes[i][prefix_len-1] != '/'
+ && path[prefix_len] != '/' && path[prefix_len] != '\0')
+ continue;
+
+ return 1;
+ }
return 0;
}
diff --git a/tests/script-14.sh b/tests/script-14.sh
new file mode 100644
index 0000000..6fa55a0
--- /dev/null
+++ b/tests/script-14.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+# check that paths don't accidentally match other files by prefix
+[ "${at_xfail}" = "yes" ] && exit 77 # see script-0
+
+(
+# This clobbers all existing writable paths for this one write.
+SANDBOX_PREDICT=/dev/null
+SANDBOX_WRITE="${PWD}/foo"
+echo FAIL >foobar
+)
+# the write to 'logfoobar' should be rejected since only 'log'
+# is supposed to be writable
+if [ $? -eq 0 ] ; then
+ exit 1
+fi
+
+# and we should have gotten a sandbox violation
+test -s "${SANDBOX_LOG}"
+
+exit $?
diff --git a/tests/script.at b/tests/script.at
index 58a5077..9134ac1 100644
--- a/tests/script.at
+++ b/tests/script.at
@@ -11,3 +11,4 @@ SB_CHECK(10)
SB_CHECK(11)
SB_CHECK(12)
SB_CHECK(13)
+SB_CHECK(14)