Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(121)

Unified Diff: sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc

Issue 11363212: Added support for greylisting of system calls. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed reviewer's comments Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
index 8ea23d9e188811707396c686a9867317ab54c9c0..d5d3478a4631666e2322da14377b6a9a91ab7b46 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
@@ -5,6 +5,7 @@
#include <ostream>
#include "sandbox/linux/seccomp-bpf/bpf_tests.h"
+#include "sandbox/linux/seccomp-bpf/syscall.h"
#include "sandbox/linux/seccomp-bpf/verifier.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -264,4 +265,121 @@ BPF_TEST(SandboxBpf, ArmPrivatePolicy, ArmPrivatePolicy) {
}
#endif // defined(__arm__)
+intptr_t CountSyscalls(const struct arch_seccomp_data& args, void *aux) {
+ // Count all invocations of our callback function.
+ ++*reinterpret_cast<int *>(aux);
+
+ // Verify that within the callback function all filtering is temporarily
+ // disabled.
+ BPF_ASSERT(syscall(__NR_getpid) > 1);
+
+ // Verify that we can now call the underlying system call without causing
+ // infinite recursion.
+ return (intptr_t)(syscall(args.nr, args.args[0], args.args[1],
+ args.args[2], args.args[3],
+ args.args[4], args.args[5]));
+}
+
+ErrorCode GreyListedPolicy(int sysno, void *aux) {
+ // The use of UnsafeTrap() causes us to print a warning message. This is
+ // generally desirable, but it results in the unittest failing, as it doesn't
+ // expect any messages on "stderr". So, temporarily disable messages. The
+ // BPF_TEST() is guaranteed to turn messages back on, after the policy
+ // function has completed.
+ Die::SuppressInfoMessages(true);
+
+ // Some system calls must always be allowed, if our policy wants to make
+ // use of UnsafeTrap()
+ if (sysno == __NR_rt_sigprocmask ||
+ sysno == __NR_rt_sigreturn
+#if defined(__NR_sigprocmask)
+ || sysno == __NR_sigprocmask
+#endif
+#if defined(__NR_sigreturn)
+ || sysno == __NR_sigreturn
+#endif
+ ) {
+ return ErrorCode(ErrorCode::ERR_ALLOWED);
+ } else if (sysno == __NR_getpid) {
+ // Disallow getpid()
+ return ErrorCode(EPERM);
+ } else if (Sandbox::isValidSyscallNumber(sysno)) {
+ // Allow (and count) all other system calls.
+ return Sandbox::UnsafeTrap(CountSyscalls, aux);
+ } else {
+ return ErrorCode(ENOSYS);
+ }
+}
+
+BPF_TEST(SandboxBpf, GreyListedPolicy,
+ GreyListedPolicy, int /* BPF_AUX */) {
+ BPF_ASSERT(syscall(__NR_getpid) == -1);
+ BPF_ASSERT(errno == EPERM);
+ BPF_ASSERT(BPF_AUX == 0);
+ BPF_ASSERT(syscall(__NR_geteuid) == syscall(__NR_getuid));
+ BPF_ASSERT(BPF_AUX == 2);
+}
+
+intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void *) {
+ return (intptr_t)(syscall(args.nr,
+ (void *)args.args[0], (void *)args.args[1],
+ (void *)args.args[2], (void *)args.args[3],
+ (void *)args.args[4], (void *)args.args[5]));
+}
+
+ErrorCode RedirectAllSyscallsPolicy(int sysno, void *aux) {
+ Die::SuppressInfoMessages(true);
+
+ // Some system calls must always be allowed, if our policy wants to make
+ // use of UnsafeTrap()
+ if (sysno == __NR_rt_sigprocmask ||
+ sysno == __NR_rt_sigreturn
+#if defined(__NR_sigprocmask)
+ || sysno == __NR_sigprocmask
+#endif
+#if defined(__NR_sigreturn)
+ || sysno == __NR_sigreturn
+#endif
+ ) {
+ return ErrorCode(ErrorCode::ERR_ALLOWED);
+ } else if (Sandbox::isValidSyscallNumber(sysno)) {
+ return Sandbox::UnsafeTrap(AllowRedirectedSyscall, aux);
+ } else {
+ return ErrorCode(ENOSYS);
+ }
+}
+
+int bus_handler_fd_ = -1;
+
+void SigBusHandler(int, siginfo_t *info, void *void_context) {
+ BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1);
+}
+
jln (very slow on Chromium) 2012/11/20 01:08:31 Could you add a small explaination, saying that SI
+BPF_TEST(SandboxBpf, SigBus, RedirectAllSyscallsPolicy) {
+ int fds[2];
+ BPF_ASSERT(pipe(fds) == 0);
+ bus_handler_fd_ = fds[1];
+ struct sigaction sa = { };
+ sa.sa_sigaction = SigBusHandler;
+ sa.sa_flags = SA_SIGINFO;
+ BPF_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0);
+ raise(SIGBUS);
+ char c = '\000';
+ BPF_ASSERT(read(fds[0], &c, 1) == 1);
+ BPF_ASSERT(close(fds[0]) == 0);
+ BPF_ASSERT(close(fds[1]) == 0);
+ BPF_ASSERT(c == 0x55);
+}
+
jln (very slow on Chromium) 2012/11/20 01:08:31 Same thing, please add a small note about what thi
+BPF_TEST(SandboxBpf, SigMask, RedirectAllSyscallsPolicy) {
+ sigset_t mask0, mask1, mask2;
+ sigemptyset(&mask0);
jln (very slow on Chromium) 2012/11/20 01:08:31 Please add comments, to make this faster to read.
+ BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, &mask1));
+ BPF_ASSERT(!sigismember(&mask1, SIGUSR1));
+ sigaddset(&mask0, SIGUSR1);
+ BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, NULL));
+ BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, &mask2));
+ BPF_ASSERT( sigismember(&mask2, SIGUSR1));
+}
+
} // namespace

Powered by Google App Engine
This is Rietveld 408576698