summaryrefslogtreecommitdiffstats
path: root/sandbox
diff options
context:
space:
mode:
authorjln@chromium.org <jln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-09 23:56:49 +0000
committerjln@chromium.org <jln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-09 23:56:49 +0000
commit803b4cafd7db254d6270706addfd6e06542b0ae3 (patch)
tree55e90050e9f981cb8a65aa9c30a782e756f23593 /sandbox
parente395b6f38cc899ea7ae37dd70f911cd45cd91bc7 (diff)
downloadchromium_src-803b4cafd7db254d6270706addfd6e06542b0ae3.zip
chromium_src-803b4cafd7db254d6270706addfd6e06542b0ae3.tar.gz
chromium_src-803b4cafd7db254d6270706addfd6e06542b0ae3.tar.bz2
Seccomp-BPF: add a new synthetic unittest
This adds a synthetic but slightly more complex unittest for the BPF compiler. BUG=130662 TEST= Review URL: https://chromiumcodereview.appspot.com/10693019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@145800 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox')
-rw-r--r--sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc59
1 files changed, 59 insertions, 0 deletions
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
index a661c8d..ce54f87 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
@@ -198,4 +198,63 @@ TEST(SandboxBpf, BasicBlacklistWithSigsys) {
TryPolicyInProcess(BlacklistNanosleepPolicySigsys, NanosleepProcessSigsys);
}
+// A more complex, but synthetic policy. This tests the correctness of the BPF
+// program by iterating through all syscalls and checking for an errno that
+// depends on the syscall number. Unlike the Verifier, this exercises the BPF
+// interpreter in the kernel.
+
+// We try to make sure we exercise optimizations in the BPF compiler. We make
+// sure that the compiler can have an opportunity to coalesce syscalls with
+// contiguous numbers and we also make sure that disjoint sets can return the
+// same errno.
+int SysnoToRandomErrno(int sysno) {
+ // Small contiguous sets of 3 system calls return an errno equal to the
+ // index of that set + 1 (so that we never return a NUL errno).
+ return ((sysno & ~3) >> 2) % 29 + 1;
+}
+
+Sandbox::ErrorCode SyntheticPolicy(int sysno) {
+ if (sysno < static_cast<int>(MIN_SYSCALL) ||
+ sysno > static_cast<int>(MAX_SYSCALL)) {
+ // FIXME: we should really not have to do that in a trivial policy.
+ return ENOSYS;
+ }
+ if (sysno == __NR_exit_group) {
+ // exit_group() is special, we really need it to work.
+ return Sandbox::SB_ALLOWED;
+ } else {
+ return SysnoToRandomErrno(sysno);
+ }
+}
+
+void SyntheticProcess(void) {
+ // 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);
+ }
+ for (int syscall_number = static_cast<int>(MIN_SYSCALL);
+ syscall_number <= static_cast<int>(MAX_SYSCALL);
+ ++syscall_number) {
+ if (syscall_number == __NR_exit_group) {
+ // exit_group() is special
+ 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);
+ }
+ }
+ ExitGroup(kExpectedReturnValue);
+}
+
+TEST(SandboxBpf, SyntheticPolicy) {
+ TryPolicyInProcess(SyntheticPolicy, SyntheticProcess);
+}
+
} // namespace