Fix error reporting when sandboxed process is signaled.
BUG=None
TEST=Unittests pass.
TEST=security_Minijail_seccomp passes on leon.
TEST=/usr/bin/yes; killall yes; echo $? prints 143.
TEST=minijail0 -- /usr/bin/yes; killall yes; echo $? prints 143 (not 253).
TEST=minijail0 -S /dev/null -- /usr/bin/yes; echo $? prints 253.
Change-Id: I62f779da9b5b3a61f6aff4c9855e5b73669c9efe
Reviewed-on: https://chromium-review.googlesource.com/195627
Reviewed-by: Nam Nguyen <namnguyen@chromium.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
Commit-Queue: Jorge Lucangeli Obes <jorgelo@chromium.org>
diff --git a/libminijail.c b/libminijail.c
index c764f81..fee657d 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -1198,10 +1198,25 @@
return -errno;
if (!WIFEXITED(st)) {
- if (WIFSIGNALED(st))
+ int error_status = st;
+ if (WIFSIGNALED(st)) {
+ int signum = WTERMSIG(st);
warn("child process %d received signal %d",
- j->initpid, WTERMSIG(st));
- return MINIJAIL_ERR_JAIL;
+ j->initpid, signum);
+ /*
+ * We return MINIJAIL_ERR_JAIL if the process received
+ * SIGSYS, which happens when a syscall is blocked by
+ * seccomp filters.
+ * If not, we do what bash(1) does:
+ * $? = 128 + signum
+ */
+ if (signum == SIGSYS) {
+ error_status = MINIJAIL_ERR_JAIL;
+ } else {
+ error_status = 128 + signum;
+ }
+ }
+ return error_status;
}
int exit_status = WEXITSTATUS(st);
diff --git a/syscall_filter_unittest.c b/syscall_filter_unittest.c
index 68551f3..fb903c5 100644
--- a/syscall_filter_unittest.c
+++ b/syscall_filter_unittest.c
@@ -518,6 +518,8 @@
__NR_rt_sigreturn);
EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7,
__NR_exit);
+ EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9, BPF_RET+BPF_K,
+ SECCOMP_RET_KILL);
free(actual.filter);
fclose(policy);
@@ -549,6 +551,8 @@
__NR_rt_sigreturn);
EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7,
__NR_exit);
+ EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9, BPF_RET+BPF_K,
+ SECCOMP_RET_KILL);
free(actual.filter);
fclose(policy);