Chromium Code Reviews| Index: sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc |
| diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc |
| index 13f40e31b31cac31ef9e8830bd12bd0528c1e64a..80c7371b17bcd3fac9416565c2994eb0a71c44ef 100644 |
| --- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc |
| +++ b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc |
| @@ -5,12 +5,17 @@ |
| #include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h" |
| #include <errno.h> |
| +#include <sched.h> |
| +#include <signal.h> |
| #include <sys/stat.h> |
| +#include <sys/socket.h> |
| #include <sys/syscall.h> |
| #include <sys/types.h> |
| #include <sys/wait.h> |
| #include <unistd.h> |
| +#include "base/files/scoped_file.h" |
| +#include "base/macros.h" |
| #include "base/posix/eintr_wrapper.h" |
| #include "base/threading/thread.h" |
| #include "build/build_config.h" |
| @@ -46,6 +51,41 @@ TEST(BaselinePolicy, HandlePostForkReturn) { |
| HandlePostForkReturn(pid); |
| } |
| +// This also tests that read(), write() and fstat() are allowed. |
| +void TestPipeOrSocketPair(base::ScopedFD read_end, base::ScopedFD write_end) { |
| + BPF_ASSERT_LE(0, read_end.get()); |
| + BPF_ASSERT_LE(0, write_end.get()); |
| + struct stat stat_buf; |
| + int sys_ret = fstat(read_end.get(), &stat_buf); |
| + BPF_ASSERT_EQ(0, sys_ret); |
| + BPF_ASSERT(S_ISFIFO(stat_buf.st_mode) || S_ISSOCK(stat_buf.st_mode)); |
| + |
| + const ssize_t kTestTransferSize = 4; |
| + static const char kTestString[kTestTransferSize] = {'T', 'E', 'S', 'T'}; |
| + ssize_t transfered = 0; |
| + |
| + transfered = |
| + HANDLE_EINTR(write(write_end.get(), kTestString, kTestTransferSize)); |
| + BPF_ASSERT_EQ(kTestTransferSize, transfered); |
| + char read_buf[kTestTransferSize + 1] = {0}; |
| + transfered = HANDLE_EINTR(read(read_end.get(), read_buf, sizeof(read_buf))); |
| + BPF_ASSERT_EQ(kTestTransferSize, transfered); |
| + BPF_ASSERT_EQ(0, bcmp(kTestString, read_buf, kTestTransferSize)); |
|
mdempsky
2014/05/17 00:59:43
s/bcmp/memcmp/ and #include <string.h> (bcmp was r
jln (very slow on Chromium)
2014/05/17 01:29:47
Done.
|
| +} |
| + |
| +// Test that a few easy-to-test system calls are allowed. |
| +BPF_TEST_C(BaselinePolicy, BaselinePolicyBasicAllowed, BaselinePolicy) { |
| + BPF_ASSERT_EQ(0, sched_yield()); |
| + |
| + int pipefd[2]; |
| + int sys_ret = pipe(pipefd); |
| + BPF_ASSERT_EQ(0, sys_ret); |
| + TestPipeOrSocketPair(base::ScopedFD(pipefd[0]), base::ScopedFD(pipefd[1])); |
| + |
| + BPF_ASSERT_LE(1, getpid()); |
| + BPF_ASSERT_LE(0, getuid()); |
| +} |
| + |
| BPF_TEST_C(BaselinePolicy, FchmodErrno, BaselinePolicy) { |
| int ret = fchmod(-1, 07777); |
| BPF_ASSERT_EQ(-1, ret); |
| @@ -109,6 +149,99 @@ BPF_DEATH_TEST_C(BaselinePolicy, |
| HandlePostForkReturn(pid); |
| } |
| +BPF_DEATH_TEST_C(BaselinePolicy, |
| + DisallowedKillCrashes, |
| + DEATH_MESSAGE(GetKillErrorMessageContentForTests()), |
| + BaselinePolicy) { |
| + BPF_ASSERT_NE(1, getpid()); |
| + kill(1, SIGCONT); |
|
mdempsky
2014/05/17 00:59:43
I assume you picked SIGCONT because it won't do an
jln (very slow on Chromium)
2014/05/17 01:29:47
Done.
|
| + _exit(1); |
| +} |
| + |
| +BPF_TEST_C(BaselinePolicy, CanKillSelf, BaselinePolicy) { |
| + int sys_ret = kill(getpid(), SIGCONT); |
| + BPF_ASSERT_EQ(0, sys_ret); |
| +} |
| + |
| +BPF_TEST_C(BaselinePolicy, Socketpair, BaselinePolicy) { |
| + int sv[2]; |
| + int sys_ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sv); |
| + TestPipeOrSocketPair(base::ScopedFD(sv[0]), base::ScopedFD(sv[1])); |
| + |
| + sys_ret = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sv); |
| + TestPipeOrSocketPair(base::ScopedFD(sv[0]), base::ScopedFD(sv[1])); |
| +} |
| + |
| +// Not all architectures can restrict the domain for socketpair(). |
| +#if defined(__x86_64__) || defined(__arm__) |
| +BPF_DEATH_TEST_C(BaselinePolicy, |
| + SocketpairWrongDomain, |
| + DEATH_MESSAGE(GetErrorMessageContentForTests()), |
| + BaselinePolicy) { |
| + int sv[2]; |
| + ignore_result(socketpair(AF_INET, SOCK_STREAM, 0, sv)); |
| + _exit(1); |
| +} |
| +#endif // defined(__x86_64__) || defined(__arm__) |
| + |
| +BPF_TEST_C(BaselinePolicy, EPERM_open, BaselinePolicy) { |
| + errno = 0; |
| + int sys_ret = open("/proc/cpuinfo", O_RDONLY); |
| + BPF_ASSERT_EQ(-1, sys_ret); |
| + BPF_ASSERT_EQ(EPERM, errno); |
| +} |
| + |
| +BPF_TEST_C(BaselinePolicy, EPERM_access, BaselinePolicy) { |
| + errno = 0; |
| + int sys_ret = access("/proc/cpuinfo", R_OK); |
| + BPF_ASSERT_EQ(-1, sys_ret); |
| + BPF_ASSERT_EQ(EPERM, errno); |
| +} |
| + |
| +BPF_TEST_C(BaselinePolicy, EPERM_getcwd, BaselinePolicy) { |
| + errno = 0; |
| + char buf[1024]; |
| + char* cwd = getcwd(buf, sizeof(buf)); |
| + BPF_ASSERT_EQ(NULL, cwd); |
| + BPF_ASSERT_EQ(EPERM, errno); |
| +} |
| + |
| +// A failing test using this macro could be problematic since we perform |
| +// system calls by passing "0" as every argument. |
| +// The kernel could SIGSEGV the process or the system call itself could reboot |
| +// the machine. Some thoughts have been given when hand-picking the system |
| +// calls below to limit any potential side effects outside of the current |
| +// process. |
| +#define TEST_BASELINE_SIGSYS(sysno) \ |
| + BPF_DEATH_TEST_C(BaselinePolicy, \ |
| + SIGSYS_##sysno, \ |
| + DEATH_MESSAGE(GetErrorMessageContentForTests()), \ |
| + BaselinePolicy) { \ |
| + syscall(sysno, 0, 0, 0, 0, 0, 0); \ |
| + _exit(1); \ |
| + } |
| + |
| +TEST_BASELINE_SIGSYS(__NR_syslog); |
| +TEST_BASELINE_SIGSYS(__NR_sched_setaffinity); |
| +TEST_BASELINE_SIGSYS(__NR_timer_create); |
| +TEST_BASELINE_SIGSYS(__NR_io_cancel); |
| +TEST_BASELINE_SIGSYS(__NR_ptrace); |
| +TEST_BASELINE_SIGSYS(__NR_eventfd); |
| +TEST_BASELINE_SIGSYS(__NR_fgetxattr); |
| +TEST_BASELINE_SIGSYS(__NR_fanotify_init); |
| +TEST_BASELINE_SIGSYS(__NR_swapon); |
| +TEST_BASELINE_SIGSYS(__NR_chroot); |
| +TEST_BASELINE_SIGSYS(__NR_acct); |
| +TEST_BASELINE_SIGSYS(__NR_sysinfo); |
| +TEST_BASELINE_SIGSYS(__NR_inotify_init); |
| +TEST_BASELINE_SIGSYS(__NR_init_module); |
| +TEST_BASELINE_SIGSYS(__NR_keyctl); |
| +TEST_BASELINE_SIGSYS(__NR_mq_open); |
| +TEST_BASELINE_SIGSYS(__NR_vserver); |
| +TEST_BASELINE_SIGSYS(__NR_getcpu); |
| +TEST_BASELINE_SIGSYS(__NR_setpgid); |
| +TEST_BASELINE_SIGSYS(__NR_getitimer); |
| + |
| #endif // !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER) && |
| // !defined(MEMORY_SANITIZER) |