// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" #include #include #include #include #include "base/files/scoped_file.h" #include "base/posix/eintr_wrapper.h" #include "sandbox/linux/tests/unit_tests.h" #include "testing/gtest/include/gtest/gtest.h" namespace sandbox { namespace { // NOTE: most tests for the SandboxBPF class are currently in // integration_tests/. TEST(SandboxBPF, CreateDestroy) { // Give an opportunity to dynamic tools to perform some simple testing. SandboxBPF sandbox(nullptr); SandboxBPF* sandbox_ptr = new SandboxBPF(nullptr); delete sandbox_ptr; } // This test should execute no matter whether we have kernel support. So, // we make it a TEST() instead of a BPF_TEST(). TEST(SandboxBPF, DISABLE_ON_TSAN(CallSupports)) { // We check that we don't crash, but it's ok if the kernel doesn't // support it. bool seccomp_bpf_supported = SandboxBPF::SupportsSeccompSandbox( SandboxBPF::SeccompLevel::SINGLE_THREADED); bool seccomp_bpf_tsync_supported = SandboxBPF::SupportsSeccompSandbox( SandboxBPF::SeccompLevel::MULTI_THREADED); // We want to log whether or not seccomp BPF is actually supported // since actual test coverage depends on it. std::cout << "Seccomp BPF supported (single thread): " << (seccomp_bpf_supported ? "true." : "false.") << "\n"; std::cout << "Seccomp BPF supported (multi thread): " << (seccomp_bpf_tsync_supported ? "true." : "false.") << "\n"; std::cout << "Pointer size: " << sizeof(void*) << "\n"; } SANDBOX_TEST(SandboxBPF, DISABLE_ON_TSAN(CallSupportsTwice)) { bool single1 = SandboxBPF::SupportsSeccompSandbox( SandboxBPF::SeccompLevel::SINGLE_THREADED); bool single2 = SandboxBPF::SupportsSeccompSandbox( SandboxBPF::SeccompLevel::SINGLE_THREADED); ASSERT_EQ(single1, single2); bool multi1 = SandboxBPF::SupportsSeccompSandbox( SandboxBPF::SeccompLevel::MULTI_THREADED); bool multi2 = SandboxBPF::SupportsSeccompSandbox( SandboxBPF::SeccompLevel::MULTI_THREADED); ASSERT_EQ(multi1, multi2); // Multi threaded support implies single threaded support. if (multi1) { ASSERT_TRUE(single1); } } TEST(SandboxBPF, ProcTaskFdDescriptorGetsClosed) { int pipe_fds[2]; ASSERT_EQ(0, pipe(pipe_fds)); base::ScopedFD read_end(pipe_fds[0]); base::ScopedFD write_end(pipe_fds[1]); { SandboxBPF sandbox(nullptr); sandbox.SetProcFd(std::move(write_end)); } ASSERT_EQ(0, fcntl(read_end.get(), F_SETFL, O_NONBLOCK)); char c; // Check that the sandbox closed the write_end (read will EOF instead of // returning EWOULDBLOCK). ASSERT_EQ(0, read(read_end.get(), &c, 1)); } } // namespace } // sandbox