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

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

Issue 10878033: Simplified unit testing of sandboxing code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months 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 54fe7a7bff7bec3748b7a3a4c54eddb007724f07..19c64a9bd2983591a2e2d08fd80bdf2841ca47a1 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
@@ -4,7 +4,7 @@
#include <ostream>
-#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
+#include "sandbox/linux/seccomp-bpf/bpf_tests.h"
#include "sandbox/linux/seccomp-bpf/verifier.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -17,6 +17,8 @@ const int kExpectedReturnValue = 42;
const int kArmPublicSysnoCeiling = __NR_SYSCALL_BASE + 1024;
#endif
+// This test should execute no matter whether we have kernel support. So,
+// we make it a TEST() instead of a BPF_TEST().
TEST(SandboxBpf, CallSupports) {
// We check that we don't crash, but it's ok if the kernel doesn't
// support it.
@@ -31,9 +33,10 @@ TEST(SandboxBpf, CallSupports) {
<< "\n";
}
-TEST(SandboxBpf, CallSupportsTwice) {
+BPF_TEST(SandboxBpf, CallSupportsTwice) {
Sandbox::supportsSeccompSandbox(-1);
Sandbox::supportsSeccompSandbox(-1);
+ return true;
}
__attribute__((noreturn)) void DoCrash() {
@@ -63,50 +66,20 @@ __attribute__((noreturn)) void ExitGroup(int status) {
// Helper function to start a sandbox with a policy specified in
// evaluator
void StartSandboxOrDie(Sandbox::EvaluateSyscall evaluator) {
- int proc_fd = open("/proc", O_RDONLY|O_DIRECTORY);
- if (proc_fd < 0 || !evaluator) {
- ExitGroup(1);
- }
- if (Sandbox::supportsSeccompSandbox(proc_fd) !=
- Sandbox::STATUS_AVAILABLE) {
- ExitGroup(1);
- }
+ BPF_ASSERT(evaluator);
+
+ // Ensure the the sandbox is actually available at this time
+ int proc_fd;
+ BPF_ASSERT((proc_fd = open("/proc", O_RDONLY|O_DIRECTORY)) >= 0);
+ BPF_ASSERT(Sandbox::supportsSeccompSandbox(proc_fd) ==
+ Sandbox::STATUS_AVAILABLE);
+
+ // Initialize and then start the sandbox with our custom policy
Sandbox::setProcFd(proc_fd);
Sandbox::setSandboxPolicy(evaluator, NULL);
Sandbox::startSandbox();
}
-void RunInSandbox(Sandbox::EvaluateSyscall evaluator,
- void (*SandboxedCode)()) {
- // TODO(markus): Implement IsEqual for ErrorCode
- // IsEqual(evaluator(__NR_exit_group), Sandbox::SB_ALLOWED) <<
- // "You need to always allow exit_group() in your test policy";
- StartSandboxOrDie(evaluator);
- // TODO(jln): find a way to use the testing framework inside
- // SandboxedCode() or at the very least to surface errors
- SandboxedCode();
- // SandboxedCode() should have exited, this is a failure
- ExitGroup(1);
-}
-
-// evaluator should always allow ExitGroup
-// SandboxedCode should ExitGroup(kExpectedReturnValue) if and only if
-// things go as expected.
-void TryPolicyInProcess(Sandbox::EvaluateSyscall evaluator,
- void (*SandboxedCode)()) {
- // TODO(jln) figure out a way to surface whether we're actually testing
- // something or not.
- if (Sandbox::supportsSeccompSandbox(-1) == Sandbox::STATUS_AVAILABLE) {
- EXPECT_EXIT(RunInSandbox(evaluator, SandboxedCode),
- ::testing::ExitedWithCode(kExpectedReturnValue),
- "");
- } else {
- // The sandbox is not available. We should still try to exercise what we
- // can.
- // TODO(markus): (crbug.com/141545) let us call the compiler from here.
- Sandbox::setSandboxPolicy(evaluator, NULL);
- }
-}
// A simple blacklist test
@@ -124,17 +97,16 @@ Sandbox::ErrorCode BlacklistNanosleepPolicy(int sysno) {
}
}
-void NanosleepProcess(void) {
+BPF_TEST(SandboxBpf, ApplyBasicBlacklistPolicy) {
+ StartSandboxOrDie(BlacklistNanosleepPolicy);
+
+ // nanosleep() should be denied
const struct timespec ts = {0, 0};
errno = 0;
- if(syscall(__NR_nanosleep, &ts, NULL) != -1 || errno != EACCES) {
- ExitGroup(1);
- }
- ExitGroup(kExpectedReturnValue);
-}
+ BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1);
+ BPF_ASSERT(errno == EACCES);
-TEST(SandboxBpf, ApplyBasicBlacklistPolicy) {
- TryPolicyInProcess(BlacklistNanosleepPolicy, NanosleepProcess);
+ return true;
}
// Now do a simple whitelist test
@@ -149,19 +121,19 @@ Sandbox::ErrorCode WhitelistGetpidPolicy(int sysno) {
}
}
-void GetpidProcess(void) {
- errno = 0;
+BPF_TEST(SandboxBpf, ApplyBasicWhitelistPolicy) {
+ StartSandboxOrDie(WhitelistGetpidPolicy);
+
// getpid() should be allowed
- if (syscall(__NR_getpid) < 0 || errno)
- ExitGroup(1);
+ errno = 0;
+ BPF_ASSERT(syscall(__NR_getpid) > 0);
+ BPF_ASSERT(errno == 0);
+
// getpgid() should be denied
- if (getpgid(0) != -1 || errno != ENOMEM)
- ExitGroup(1);
- ExitGroup(kExpectedReturnValue);
-}
+ BPF_ASSERT(getpgid(0) == -1);
+ BPF_ASSERT(errno == ENOMEM);
-TEST(SandboxBpf, ApplyBasicWhitelistPolicy) {
- TryPolicyInProcess(WhitelistGetpidPolicy, GetpidProcess);
+ return true;
}
// A simple blacklist policy, with a SIGSYS handler
@@ -194,26 +166,25 @@ Sandbox::ErrorCode BlacklistNanosleepPolicySigsys(int sysno) {
}
}
-void NanosleepProcessSigsys(void) {
- const struct timespec ts = {0, 0};
- errno = 0;
+BPF_TEST(SandboxBpf, BasicBlacklistWithSigsys) {
+ StartSandboxOrDie(BlacklistNanosleepPolicySigsys);
+
// getpid() should work properly
- if (syscall(__NR_getpid) < 0)
- ExitGroup(1);
+ errno = 0;
+ BPF_ASSERT(syscall(__NR_getpid) > 0);
+ BPF_ASSERT(errno == 0);
+
// Our Auxiliary Data, should be reset by the signal handler
BlacklistNanosleepPolicySigsysAuxData = -1;
- errno = 0;
- if (syscall(__NR_nanosleep, &ts, NULL) != -1 || errno != ENOMEM)
- ExitGroup(1);
+ const struct timespec ts = {0, 0};
+ BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1);
+ BPF_ASSERT(errno == ENOMEM);
+
// We expect the signal handler to modify AuxData
- if (BlacklistNanosleepPolicySigsysAuxData != kExpectedReturnValue)
- ExitGroup(1);
- else
- ExitGroup(kExpectedReturnValue);
-}
+ BPF_ASSERT(
+ BlacklistNanosleepPolicySigsysAuxData == kExpectedReturnValue);
-TEST(SandboxBpf, BasicBlacklistWithSigsys) {
- TryPolicyInProcess(BlacklistNanosleepPolicySigsys, NanosleepProcessSigsys);
+ return true;
}
// A more complex, but synthetic policy. This tests the correctness of the BPF
@@ -252,13 +223,14 @@ Sandbox::ErrorCode SyntheticPolicy(int sysno) {
}
}
-void SyntheticProcess(void) {
+BPF_TEST(SandboxBpf, SyntheticPolicy) {
// Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int
// overflow.
- if (std::numeric_limits<int>::max() - kExpectedReturnValue - 1 <
- static_cast<int>(MAX_SYSCALL)) {
- ExitGroup(1);
- }
+ BPF_ASSERT(
+ std::numeric_limits<int>::max() - kExpectedReturnValue - 1 >=
+ static_cast<int>(MAX_SYSCALL));
+
+ StartSandboxOrDie(SyntheticPolicy);
// TODO(jorgelo): remove this limit once crbug.com/141694 is fixed.
#if defined(__arm__)
@@ -275,19 +247,10 @@ void SyntheticProcess(void) {
continue;
}
errno = 0;
- if (syscall(syscall_number) != -1 ||
- errno != SysnoToRandomErrno(syscall_number)) {
- // Exit with a return value that is different than kExpectedReturnValue
- // to signal an error. Make it easy to see what syscall_number failed in
- // the test report.
- ExitGroup(kExpectedReturnValue + syscall_number + 1);
- }
+ BPF_ASSERT(syscall(syscall_number) == -1);
+ BPF_ASSERT(errno == SysnoToRandomErrno(syscall_number));
}
- ExitGroup(kExpectedReturnValue);
-}
-
-TEST(SandboxBpf, SyntheticPolicy) {
- TryPolicyInProcess(SyntheticPolicy, SyntheticProcess);
+ return true;
}
} // namespace

Powered by Google App Engine
This is Rietveld 408576698