diff options
authorSergei Trofimovich <slyfox@gentoo.org>2019-12-25 00:39:13 +0000
committerMichał Górny <mgorny@gentoo.org>2020-05-31 09:38:28 +0200
commit24fd102c99763502a7ab0d1f6f26632673216371 (patch)
parentlibsandbox/libsandbox.c: add errno output for internal sandbox violations (diff)
check_syscall(): turn internal sandbox violation into denywrite
In #590084 test suite performed to list files in a deleted directory: $ sandbox 'mkdir /tmp/zzz; cd /tmp/zzz; rmdir /tmp/zzz; ls' * sandbox-2.18/libsandbox/libsandbox.c:check_syscall():974: failure (No such file or directory): * ISE: opendir(.) abs_path: (null) res_path: (null) Another reproducer is to create file outside deleted directory relative to that directory: $ sandbox 'mkdir /tmp/zzz; cd /tmp/zzz; rmdir /tmp/zzz; touch ../foo' * sandbox-2.18/libsandbox/libsandbox.c:check_syscall():974: failure (No such file or directory): * ISE: open_wr(../foo) abs_path: (null) res_path: (null) sandbox can't validate safety of any of these operations as kernel does not provide a mechanism to resolve '.' back to an absolute path. As it's a rare condition let's turn it into a sandbox violation instead of internal sandbox error and link to the bug with details in the error message. Report after the change looks like: $ ./sandbox.sh 'mkdir /tmp/zzz; cd /tmp/zzz; rmdir /tmp/zzz; touch ../foo' * ACCESS DENIED: open_wr: '../foo' (from deleted directory, see https://bugs.gentoo.org/590084) * ACCESS DENIED: utimensat: '../foo' (from deleted directory, see https://bugs.gentoo.org/590084) touch: cannot touch '../foo': Permission denied Reported-by: Mike Gilbert Bug: https://bugs.gentoo.org/590084 Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org> Signed-off-by: Michał Górny <mgorny@gentoo.org>
3 files changed, 21 insertions, 0 deletions
diff --git a/libsandbox/libsandbox.c b/libsandbox/libsandbox.c
index 0ee92ae..b4d732d 100644
--- a/libsandbox/libsandbox.c
+++ b/libsandbox/libsandbox.c
@@ -970,6 +970,15 @@ static int check_syscall(sbcontext_t *sbcontext, int sb_nr, const char *func,
if (trace_pid && errno == ESRCH)
return 2;
+ /* Underlying directory we operate on went away: #590084 */
+ if (!absolute_path && !resolved_path && errno == ENOENT) {
+ int sym_len = SB_MAX_STRING_LEN + 1 - strlen(func);
+ if (sbcontext->show_access_violation)
+ sb_eerror("%sACCESS DENIED%s: %s:%*s'%s' (from deleted directory, see https://bugs.gentoo.org/590084)\n",
+ COLOR_RED, COLOR_NORMAL, func, sym_len, "", file);
+ return 0;
+ }
/* If we get here, something bad happened */
sb_ebort("ISE: %s(%s)\n"
"\tabs_path: %s\n"
diff --git a/tests/script-16.sh b/tests/script-16.sh
new file mode 100755
index 0000000..c668cfa
--- /dev/null
+++ b/tests/script-16.sh
@@ -0,0 +1,11 @@
+addwrite $PWD
+mkdir -p to-be/deleted
+cd to-be/deleted
+rmdir ../deleted
+# In https://bugs.gentoo.org/590084 sanbox should deny
+# access here and touch should fail:
+! touch ../foo
diff --git a/tests/script.at b/tests/script.at
index 8837bda..f1119ef 100644
--- a/tests/script.at
+++ b/tests/script.at
@@ -13,3 +13,4 @@ SB_CHECK(12)
+SB_CHECK(16) \ No newline at end of file