1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.h"
6
7#include <fcntl.h>
8#include <sys/stat.h>
9#include <sys/types.h>
10
11#include "base/basictypes.h"
12#include "base/logging.h"
13#include "base/memory/scoped_ptr.h"
14#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
15#include "sandbox/linux/tests/unit_tests.h"
16
17namespace sandbox {
18
19SandboxBPFTestRunner::SandboxBPFTestRunner(
20    BPFTesterDelegate* bpf_tester_delegate)
21    : bpf_tester_delegate_(bpf_tester_delegate) {
22}
23
24SandboxBPFTestRunner::~SandboxBPFTestRunner() {
25}
26
27void SandboxBPFTestRunner::Run() {
28  DCHECK(bpf_tester_delegate_);
29  sandbox::Die::EnableSimpleExit();
30
31  scoped_ptr<SandboxBPFPolicy> policy =
32      bpf_tester_delegate_->GetSandboxBPFPolicy();
33
34  if (sandbox::SandboxBPF::SupportsSeccompSandbox(-1) ==
35      sandbox::SandboxBPF::STATUS_AVAILABLE) {
36    // Ensure the the sandbox is actually available at this time
37    int proc_fd;
38    SANDBOX_ASSERT((proc_fd = open("/proc", O_RDONLY | O_DIRECTORY)) >= 0);
39    SANDBOX_ASSERT(sandbox::SandboxBPF::SupportsSeccompSandbox(proc_fd) ==
40                   sandbox::SandboxBPF::STATUS_AVAILABLE);
41
42    // Initialize and then start the sandbox with our custom policy
43    sandbox::SandboxBPF sandbox;
44    sandbox.set_proc_fd(proc_fd);
45    sandbox.SetSandboxPolicy(policy.release());
46    SANDBOX_ASSERT(
47        sandbox.StartSandbox(sandbox::SandboxBPF::PROCESS_SINGLE_THREADED));
48
49    // Run the actual test.
50    bpf_tester_delegate_->RunTestFunction();
51  } else {
52    printf("This BPF test is not fully running in this configuration!\n");
53    // Android and Valgrind are the only configurations where we accept not
54    // having kernel BPF support.
55    if (!IsAndroid() && !IsRunningOnValgrind()) {
56      const bool seccomp_bpf_is_supported = false;
57      SANDBOX_ASSERT(seccomp_bpf_is_supported);
58    }
59    // Call the compiler and verify the policy. That's the least we can do,
60    // if we don't have kernel support.
61    sandbox::SandboxBPF sandbox;
62    sandbox.SetSandboxPolicy(policy.release());
63    sandbox::SandboxBPF::Program* program =
64        sandbox.AssembleFilter(true /* force_verification */);
65    delete program;
66    sandbox::UnitTests::IgnoreThisTest();
67  }
68}
69
70bool SandboxBPFTestRunner::ShouldCheckForLeaks() const {
71  // LSAN requires being able to use ptrace() and other system calls that could
72  // be denied.
73  return false;
74}
75
76}  // namespace sandbox
77