mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Link more complex test cases dynamically
Linking glibc in fully static mode is mostly unsupported. While such binaries can easily be produced, conflicting symbols will often make them crash at runtime. This happens because glibc will always (try to) load some dynamically linked libraries, even when statically linked. This includes things like the resolver, unicode/locale handling and others. Internally at Google, this is not a concern due to the way glibc is being built there. But in order to make all of our tests run in the open-source version of this code, we need to change strategy a bit. As a rule of thumb, glibc can safely be linked statically if a program is resonably simple and does not use any networking of locale dependent facilities. Calling syscalls directly instead of the corresponding libc wrappers works as well, of course. This change adjusts linker flags and sandbox policies to be more compatible with regular Linux distributions. Tested: - `ctest -R '[A-Z].*'` (all SAPI/Sandbox2 tests) PiperOrigin-RevId: 429025901 Change-Id: I46b677d9eb61080a8fe868002a34a77de287bf2d
This commit is contained in:
parent
d2dfcf0800
commit
befdb09597
|
@ -59,6 +59,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|||
set(CMAKE_SKIP_BUILD_RPATH ON)
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.14)
|
||||
cmake_policy(SET CMP0083 NEW)
|
||||
include(CheckPIESupported)
|
||||
check_pie_supported()
|
||||
endif()
|
||||
|
|
|
@ -24,19 +24,21 @@ sapi_proto_library(
|
|||
name = "stringop_params_proto",
|
||||
srcs = ["stringop_params.proto"],
|
||||
visibility = ["//visibility:public"],
|
||||
alwayslink = True,
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "stringop",
|
||||
srcs = ["stringop.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
linkstatic = True,
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":stringop_params_cc_proto",
|
||||
"//sandboxed_api:lenval_core",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
],
|
||||
alwayslink = 1, # All functions are linked into dependent binaries
|
||||
alwayslink = True,
|
||||
)
|
||||
|
||||
sapi_library(
|
||||
|
|
|
@ -842,6 +842,7 @@ cc_test(
|
|||
"//sandboxed_api/util:flags",
|
||||
"//sandboxed_api/util:status_matchers",
|
||||
"//sandboxed_api/util:temp_file",
|
||||
"@com_google_absl//absl/cleanup",
|
||||
"@com_google_absl//absl/memory",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
|
|
|
@ -946,6 +946,7 @@ if(SAPI_ENABLE_TESTS)
|
|||
sandbox2::testcase_symbolize
|
||||
)
|
||||
target_link_libraries(sandbox2_stack_trace_test PRIVATE
|
||||
absl::cleanup
|
||||
absl::memory
|
||||
absl::status
|
||||
absl::strings
|
||||
|
|
|
@ -66,7 +66,7 @@ TEST(BufferTest, TestImplementation) {
|
|||
std::unique_ptr<Policy> BufferTestcasePolicy() {
|
||||
auto s2p = PolicyBuilder()
|
||||
.DisableNamespaces()
|
||||
.AllowStaticStartup()
|
||||
.AllowDynamicStartup()
|
||||
.AllowExit()
|
||||
.AllowSafeFcntl()
|
||||
.AllowTime()
|
||||
|
|
|
@ -39,6 +39,7 @@ namespace sandbox2 {
|
|||
namespace {
|
||||
|
||||
using ::sapi::GetTestSourcePath;
|
||||
using ::testing::Eq;
|
||||
|
||||
// Allow typical syscalls and call SECCOMP_RET_TRACE for personality syscall,
|
||||
// chosen because unlikely to be called by a regular program.
|
||||
|
@ -46,6 +47,7 @@ std::unique_ptr<Policy> NotifyTestcasePolicy() {
|
|||
return PolicyBuilder()
|
||||
.DisableNamespaces()
|
||||
.AllowStaticStartup()
|
||||
.AllowDynamicStartup() // For PrintPidAndComms
|
||||
.AllowExit()
|
||||
.AllowRead()
|
||||
.AllowWrite()
|
||||
|
@ -106,16 +108,12 @@ TEST(NotifyTest, AllowPersonality) {
|
|||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
const std::string path = GetTestSourcePath("sandbox2/testcases/personality");
|
||||
std::vector<std::string> args = {path};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
auto policy = NotifyTestcasePolicy();
|
||||
ASSERT_THAT(policy, testing::Not(testing::IsNull()));
|
||||
auto notify = absl::make_unique<PersonalityNotify>(true);
|
||||
|
||||
Sandbox2 s2(std::move(executor), std::move(policy), std::move(notify));
|
||||
Sandbox2 s2(absl::make_unique<Executor>(path, args), NotifyTestcasePolicy(),
|
||||
absl::make_unique<PersonalityNotify>(/*allow=*/true));
|
||||
auto result = s2.Run();
|
||||
|
||||
ASSERT_EQ(result.final_status(), Result::OK);
|
||||
ASSERT_EQ(result.reason_code(), 22);
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::OK));
|
||||
EXPECT_THAT(result.reason_code(), Eq(22));
|
||||
}
|
||||
|
||||
// Test EventSyscallTrap on personality syscall and disallow it.
|
||||
|
@ -123,16 +121,12 @@ TEST(NotifyTest, DisallowPersonality) {
|
|||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
const std::string path = GetTestSourcePath("sandbox2/testcases/personality");
|
||||
std::vector<std::string> args = {path};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
auto policy = NotifyTestcasePolicy();
|
||||
ASSERT_THAT(policy, testing::Not(testing::IsNull()));
|
||||
auto notify = absl::make_unique<PersonalityNotify>(false);
|
||||
|
||||
Sandbox2 s2(std::move(executor), std::move(policy), std::move(notify));
|
||||
Sandbox2 s2(absl::make_unique<Executor>(path, args), NotifyTestcasePolicy(),
|
||||
absl::make_unique<PersonalityNotify>(/*allow=*/false));
|
||||
auto result = s2.Run();
|
||||
|
||||
ASSERT_EQ(result.final_status(), Result::VIOLATION);
|
||||
ASSERT_EQ(result.reason_code(), __NR_personality);
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
||||
EXPECT_THAT(result.reason_code(), Eq(__NR_personality));
|
||||
}
|
||||
|
||||
// Test EventStarted by exchanging data after started but before sandboxed.
|
||||
|
@ -142,15 +136,13 @@ TEST(NotifyTest, PrintPidAndComms) {
|
|||
std::vector<std::string> args = {path};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
executor->set_enable_sandbox_before_exec(false);
|
||||
auto policy = NotifyTestcasePolicy();
|
||||
ASSERT_THAT(policy, testing::Not(testing::IsNull()));
|
||||
auto notify = absl::make_unique<PidCommsNotify>();
|
||||
|
||||
Sandbox2 s2(std::move(executor), std::move(policy), std::move(notify));
|
||||
Sandbox2 s2(std::move(executor), NotifyTestcasePolicy(),
|
||||
absl::make_unique<PidCommsNotify>());
|
||||
auto result = s2.Run();
|
||||
|
||||
ASSERT_EQ(result.final_status(), Result::OK);
|
||||
ASSERT_EQ(result.reason_code(), 33);
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::OK));
|
||||
EXPECT_THAT(result.reason_code(), Eq(33));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -79,16 +79,12 @@ TEST(PolicyTest, AMD64Syscall32PolicyAllowed) {
|
|||
const std::string path = GetTestSourcePath("sandbox2/testcases/policy");
|
||||
|
||||
std::vector<std::string> args = {path, "1"};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
|
||||
auto policy = PolicyTestcasePolicy();
|
||||
|
||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||
Sandbox2 s2(std::make_unique<Executor>(path, args), PolicyTestcasePolicy());
|
||||
auto result = s2.Run();
|
||||
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
||||
EXPECT_THAT(result.reason_code(), Eq(1)); // __NR_exit in 32-bit
|
||||
EXPECT_THAT(result.GetSyscallArch(), Eq(sapi::cpu::kX86));
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
||||
EXPECT_THAT(result.reason_code(), Eq(1)); // __NR_exit in 32-bit
|
||||
EXPECT_THAT(result.GetSyscallArch(), Eq(sapi::cpu::kX86));
|
||||
}
|
||||
|
||||
// Test that 32-bit syscalls from 64-bit for FS checks are disallowed.
|
||||
|
@ -96,17 +92,13 @@ TEST(PolicyTest, AMD64Syscall32FsAllowed) {
|
|||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
const std::string path = GetTestSourcePath("sandbox2/testcases/policy");
|
||||
std::vector<std::string> args = {path, "2"};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
|
||||
auto policy = PolicyTestcasePolicy();
|
||||
|
||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||
Sandbox2 s2(std::make_unique<Executor>(path, args), PolicyTestcasePolicy());
|
||||
auto result = s2.Run();
|
||||
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
||||
EXPECT_THAT(result.reason_code(),
|
||||
Eq(33)); // __NR_access in 32-bit
|
||||
EXPECT_THAT(result.GetSyscallArch(), Eq(sapi::cpu::kX86));
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
||||
EXPECT_THAT(result.reason_code(),
|
||||
Eq(33)); // __NR_access in 32-bit
|
||||
EXPECT_THAT(result.GetSyscallArch(), Eq(sapi::cpu::kX86));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -115,11 +107,7 @@ TEST(PolicyTest, PtraceDisallowed) {
|
|||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
const std::string path = GetTestSourcePath("sandbox2/testcases/policy");
|
||||
std::vector<std::string> args = {path, "3"};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
|
||||
auto policy = PolicyTestcasePolicy();
|
||||
|
||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||
Sandbox2 s2(std::make_unique<Executor>(path, args), PolicyTestcasePolicy());
|
||||
auto result = s2.Run();
|
||||
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
||||
|
@ -131,11 +119,7 @@ TEST(PolicyTest, CloneUntracedDisallowed) {
|
|||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
const std::string path = GetTestSourcePath("sandbox2/testcases/policy");
|
||||
std::vector<std::string> args = {path, "4"};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
|
||||
auto policy = PolicyTestcasePolicy();
|
||||
|
||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||
Sandbox2 s2(std::make_unique<Executor>(path, args), PolicyTestcasePolicy());
|
||||
auto result = s2.Run();
|
||||
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
||||
|
@ -147,11 +131,7 @@ TEST(PolicyTest, BpfDisallowed) {
|
|||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
const std::string path = GetTestSourcePath("sandbox2/testcases/policy");
|
||||
std::vector<std::string> args = {path, "5"};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
|
||||
auto policy = PolicyTestcasePolicy();
|
||||
|
||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||
Sandbox2 s2(std::make_unique<Executor>(path, args), PolicyTestcasePolicy());
|
||||
auto result = s2.Run();
|
||||
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
||||
|
@ -163,13 +143,12 @@ TEST(PolicyTest, BpfPermissionDenied) {
|
|||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
const std::string path = GetTestSourcePath("sandbox2/testcases/policy");
|
||||
std::vector<std::string> args = {path, "7"};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
|
||||
auto policy = CreatePolicyTestPolicyBuilder()
|
||||
.BlockSyscallWithErrno(__NR_bpf, EPERM)
|
||||
.BuildOrDie();
|
||||
|
||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||
Sandbox2 s2(std::make_unique<Executor>(path, args), std::move(policy));
|
||||
auto result = s2.Run();
|
||||
|
||||
// bpf(2) is not a violation due to explicit policy. EPERM is expected.
|
||||
|
@ -181,11 +160,7 @@ TEST(PolicyTest, IsattyAllowed) {
|
|||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
const std::string path = GetTestSourcePath("sandbox2/testcases/policy");
|
||||
std::vector<std::string> args = {path, "6"};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
|
||||
auto policy = PolicyTestcasePolicy();
|
||||
|
||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||
Sandbox2 s2(std::make_unique<Executor>(path, args), PolicyTestcasePolicy());
|
||||
auto result = s2.Run();
|
||||
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::OK));
|
||||
|
@ -209,11 +184,7 @@ TEST(MinimalTest, MinimalBinaryWorks) {
|
|||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
const std::string path = GetTestSourcePath("sandbox2/testcases/minimal");
|
||||
std::vector<std::string> args = {path};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
|
||||
auto policy = MinimalTestcasePolicy();
|
||||
|
||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||
Sandbox2 s2(std::make_unique<Executor>(path, args), MinimalTestcasePolicy());
|
||||
auto result = s2.Run();
|
||||
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::OK));
|
||||
|
@ -226,7 +197,6 @@ TEST(MinimalTest, MinimalSharedBinaryWorks) {
|
|||
const std::string path =
|
||||
GetTestSourcePath("sandbox2/testcases/minimal_dynamic");
|
||||
std::vector<std::string> args = {path};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
|
||||
auto policy = PolicyBuilder()
|
||||
.AllowDynamicStartup()
|
||||
|
@ -241,7 +211,7 @@ TEST(MinimalTest, MinimalSharedBinaryWorks) {
|
|||
.AddLibrariesForBinary(path)
|
||||
.BuildOrDie();
|
||||
|
||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||
Sandbox2 s2(std::make_unique<Executor>(path, args), std::move(policy));
|
||||
auto result = s2.Run();
|
||||
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::OK));
|
||||
|
@ -254,7 +224,6 @@ TEST(MallocTest, SystemMallocWorks) {
|
|||
const std::string path =
|
||||
GetTestSourcePath("sandbox2/testcases/malloc_system");
|
||||
std::vector<std::string> args = {path};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
|
||||
auto policy = PolicyBuilder()
|
||||
.AllowStaticStartup()
|
||||
|
@ -266,7 +235,7 @@ TEST(MallocTest, SystemMallocWorks) {
|
|||
#endif
|
||||
.BuildOrDie();
|
||||
|
||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||
Sandbox2 s2(std::make_unique<Executor>(path, args), std::move(policy));
|
||||
auto result = s2.Run();
|
||||
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::OK));
|
||||
|
@ -283,7 +252,6 @@ TEST(MultipleSyscalls, AddPolicyOnSyscallsWorks) {
|
|||
const std::string path =
|
||||
GetTestSourcePath("sandbox2/testcases/add_policy_on_syscalls");
|
||||
std::vector<std::string> args = {path};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
|
||||
auto policy = PolicyBuilder()
|
||||
.AllowStaticStartup()
|
||||
|
@ -337,7 +305,7 @@ TEST(MultipleSyscalls, AddPolicyOnSyscallsWorks) {
|
|||
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
||||
.BuildOrDie();
|
||||
|
||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||
Sandbox2 s2(std::make_unique<Executor>(path, args), std::move(policy));
|
||||
auto result = s2.Run();
|
||||
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::VIOLATION));
|
||||
|
|
|
@ -68,6 +68,7 @@ using ::testing::Lt;
|
|||
using ::testing::NotNull;
|
||||
using ::testing::StartsWith;
|
||||
using ::testing::StrEq;
|
||||
using ::sapi::IsOk;
|
||||
using ::sapi::StatusIs;
|
||||
|
||||
class PolicyBuilderTest : public testing::Test {
|
||||
|
@ -193,8 +194,9 @@ std::string PolicyBuilderTest::Run(std::vector<std::string> args,
|
|||
|
||||
TEST_F(PolicyBuilderTest, TestCanOnlyBuildOnce) {
|
||||
PolicyBuilder b;
|
||||
ASSERT_THAT(b.BuildOrDie(), NotNull());
|
||||
ASSERT_DEATH(b.BuildOrDie(), "Can only build policy once");
|
||||
ASSERT_THAT(b.TryBuild(), IsOk());
|
||||
EXPECT_THAT(b.TryBuild(), StatusIs(absl::StatusCode::kFailedPrecondition,
|
||||
"Can only build policy once."));
|
||||
}
|
||||
|
||||
TEST_F(PolicyBuilderTest, TestIsCopyable) {
|
||||
|
|
|
@ -61,7 +61,6 @@ TEST(SandboxCoreDumpTest, AbortWithoutCoreDumpReturnsSignaled) {
|
|||
// Don't restrict the syscalls at all.
|
||||
.DangerDefaultAllowAll()
|
||||
.TryBuild());
|
||||
|
||||
Sandbox2 sandbox(std::move(executor), std::move(policy));
|
||||
auto result = sandbox.Run();
|
||||
|
||||
|
@ -74,8 +73,9 @@ TEST(SandboxCoreDumpTest, AbortWithoutCoreDumpReturnsSignaled) {
|
|||
TEST(TsyncTest, TsyncNoMemoryChecks) {
|
||||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
const std::string path = GetTestSourcePath("sandbox2/testcases/tsync");
|
||||
std::vector<std::string> args = {path};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
|
||||
auto executor =
|
||||
absl::make_unique<Executor>(path, std::vector<std::string>{path});
|
||||
executor->set_enable_sandbox_before_exec(false);
|
||||
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(auto policy,
|
||||
|
@ -84,7 +84,6 @@ TEST(TsyncTest, TsyncNoMemoryChecks) {
|
|||
// Don't restrict the syscalls at all.
|
||||
.DangerDefaultAllowAll()
|
||||
.TryBuild());
|
||||
|
||||
Sandbox2 sandbox(std::move(executor), std::move(policy));
|
||||
auto result = sandbox.Run();
|
||||
|
||||
|
@ -93,8 +92,8 @@ TEST(TsyncTest, TsyncNoMemoryChecks) {
|
|||
ASSERT_EQ(result.reason_code(), 0);
|
||||
}
|
||||
|
||||
// Tests whether Executor(fd, args, envp) constructor works as
|
||||
// expected.
|
||||
// Tests whether Executor(fd, std::vector<std::string>{path}, envp) constructor
|
||||
// works as expected.
|
||||
TEST(ExecutorTest, ExecutorFdConstructor) {
|
||||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
|
||||
|
@ -135,7 +134,7 @@ TEST(StackTraceTest, StackTraceOnExitWorks) {
|
|||
auto result = sandbox.Run();
|
||||
|
||||
ASSERT_EQ(result.final_status(), Result::OK);
|
||||
ASSERT_THAT(result.stack_trace(), Not(IsEmpty()));
|
||||
EXPECT_THAT(result.stack_trace(), Not(IsEmpty()));
|
||||
}
|
||||
|
||||
// Tests that we return the correct state when the sandboxee was killed by an
|
||||
|
@ -158,7 +157,6 @@ TEST(RunAsyncTest, SandboxeeExternalKill) {
|
|||
sandbox.Kill();
|
||||
auto result = sandbox.AwaitResult();
|
||||
EXPECT_EQ(result.final_status(), Result::EXTERNAL_KILL);
|
||||
|
||||
EXPECT_THAT(result.GetStackTrace(), IsEmpty());
|
||||
}
|
||||
|
||||
|
@ -231,18 +229,19 @@ TEST(StarvationTest, MonitorIsNotStarvedByTheSandboxee) {
|
|||
std::vector<std::string> args = {path};
|
||||
std::vector<std::string> envs;
|
||||
auto executor = absl::make_unique<Executor>(path, args, envs);
|
||||
executor->limits()->set_walltime_limit(absl::Seconds(5));
|
||||
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(
|
||||
auto policy,
|
||||
PolicyBuilder().DisableNamespaces().DangerDefaultAllowAll().TryBuild());
|
||||
executor->limits()->set_walltime_limit(absl::Seconds(5));
|
||||
Sandbox2 sandbox(std::move(executor), std::move(policy));
|
||||
|
||||
auto start = absl::Now();
|
||||
ASSERT_THAT(sandbox.RunAsync(), IsTrue());
|
||||
auto result = sandbox.AwaitResult();
|
||||
EXPECT_THAT(result.final_status(), Eq(Result::TIMEOUT));
|
||||
auto end = absl::Now();
|
||||
auto elapsed = end - start;
|
||||
|
||||
auto elapsed = absl::Now() - start;
|
||||
EXPECT_THAT(elapsed, Lt(absl::Seconds(10)));
|
||||
}
|
||||
|
||||
|
|
|
@ -17,10 +17,13 @@
|
|||
#include <dirent.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/cleanup/cleanup.h"
|
||||
#include "sandboxed_api/util/flag.h"
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/strings/match.h"
|
||||
|
@ -49,6 +52,7 @@ using ::testing::ElementsAre;
|
|||
using ::testing::Eq;
|
||||
using ::testing::HasSubstr;
|
||||
using ::testing::IsEmpty;
|
||||
using ::testing::IsTrue;
|
||||
using ::testing::Not;
|
||||
|
||||
// Temporarily overrides a flag, restores the original flag value when it goes
|
||||
|
@ -74,27 +78,26 @@ void SymbolizationWorksCommon(
|
|||
const std::function<void(PolicyBuilder*)>& modify_policy) {
|
||||
const std::string path = GetTestSourcePath("sandbox2/testcases/symbolize");
|
||||
std::vector<std::string> args = {path, "1"};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
|
||||
std::string temp_filename = CreateNamedTempFileAndClose("/tmp/").value();
|
||||
file_util::fileops::CopyFile("/proc/cpuinfo", temp_filename, 0444);
|
||||
struct TempCleanup {
|
||||
~TempCleanup() { remove(capture->c_str()); }
|
||||
std::string* capture;
|
||||
} temp_cleanup{&temp_filename};
|
||||
|
||||
PolicyBuilder policybuilder;
|
||||
policybuilder
|
||||
// Don't restrict the syscalls at all.
|
||||
.DangerDefaultAllowAll()
|
||||
.AddFile(path)
|
||||
.AddLibrariesForBinary(path)
|
||||
.AddFileAt(temp_filename, "/proc/cpuinfo");
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string temp_filename,
|
||||
CreateNamedTempFileAndClose("/tmp/"));
|
||||
absl::Cleanup temp_cleanup = [&temp_filename] {
|
||||
remove(temp_filename.c_str());
|
||||
};
|
||||
ASSERT_THAT(
|
||||
file_util::fileops::CopyFile("/proc/cpuinfo", temp_filename, 0444),
|
||||
IsTrue());
|
||||
|
||||
auto policybuilder = PolicyBuilder()
|
||||
// Don't restrict the syscalls at all.
|
||||
.DangerDefaultAllowAll()
|
||||
.AddFile(path)
|
||||
.AddLibrariesForBinary(path)
|
||||
.AddFileAt(temp_filename, "/proc/cpuinfo");
|
||||
modify_policy(&policybuilder);
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(auto policy, policybuilder.TryBuild());
|
||||
|
||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||
Sandbox2 s2(absl::make_unique<Executor>(path, args), std::move(policy));
|
||||
auto result = s2.Run();
|
||||
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::SIGNALED));
|
||||
|
@ -187,15 +190,15 @@ TEST(StackTraceTest, SymbolizationTrustedFilesOnly) {
|
|||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
const std::string path = GetTestSourcePath("sandbox2/testcases/symbolize");
|
||||
std::vector<std::string> args = {path, "2"};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(
|
||||
auto policy, PolicyBuilder{} // Don't restrict the syscalls at all.
|
||||
.DangerDefaultAllowAll()
|
||||
.AddFile(path)
|
||||
.AddLibrariesForBinary(path)
|
||||
.TryBuild());
|
||||
|
||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(auto policy,
|
||||
PolicyBuilder()
|
||||
// Don't restrict the syscalls at all.
|
||||
.DangerDefaultAllowAll()
|
||||
.AddFile(path)
|
||||
.AddLibrariesForBinary(path)
|
||||
.TryBuild());
|
||||
Sandbox2 s2(absl::make_unique<Executor>(path, args), std::move(policy));
|
||||
auto result = s2.Run();
|
||||
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::SIGNALED));
|
||||
|
|
|
@ -14,13 +14,18 @@
|
|||
|
||||
# Description: test cases for sandbox2 unit tests.
|
||||
#
|
||||
# The following cc_binary options avoid dynamic linking which uses a lot of
|
||||
# syscalls (open, mmap, etc.):
|
||||
# linkopts = ["-static"]
|
||||
# linkstatic = 1
|
||||
# features = ["-pie"]
|
||||
# Bazel adds -pie by default but -static is incompatible with it, so we use
|
||||
# the features flag to force it off.
|
||||
# Some of the following cc_binary options avoid dynamic linking which uses a
|
||||
# lot of syscalls (open, mmap, etc.):
|
||||
# linkstatic = True Default for cc_binary
|
||||
# features = ["fully_static_link"] Adds -static
|
||||
#
|
||||
# Note that linking fully static with an unmodified glibc is not generally
|
||||
# considered safe, due to glibc relying heavily on loading shared objects at
|
||||
# runtime.
|
||||
# The rule of thumb when it is safe to do so is when the program either only
|
||||
# uses plain syscalls (bypassing any libc altogether) or if it does not use
|
||||
# any networking and none of the functionality from cstdio/stdio.h (due to
|
||||
# auto-loading of locale-specific shared objecs).
|
||||
|
||||
load("//sandboxed_api/bazel:build_defs.bzl", "sapi_platform_copts")
|
||||
|
||||
|
@ -30,37 +35,27 @@ package(default_visibility = [
|
|||
|
||||
licenses(["notice"])
|
||||
|
||||
FULLY_STATIC_FEATURES = [
|
||||
"-pie",
|
||||
"fully_static_link", # link libc statically
|
||||
]
|
||||
|
||||
cc_binary(
|
||||
name = "abort",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["abort.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
deps = ["//sandboxed_api/util:raw_logging"],
|
||||
)
|
||||
|
||||
# security: disable=cc-static-no-pie
|
||||
cc_binary(
|
||||
name = "add_policy_on_syscalls",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["add_policy_on_syscalls.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = FULLY_STATIC_FEATURES,
|
||||
linkstatic = 1,
|
||||
features = ["fully_static_link"],
|
||||
)
|
||||
|
||||
# security: disable=cc-static-no-pie
|
||||
cc_binary(
|
||||
name = "buffer",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["buffer.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = FULLY_STATIC_FEATURES,
|
||||
linkstatic = 1,
|
||||
deps = [
|
||||
"//sandboxed_api/sandbox2:buffer",
|
||||
"//sandboxed_api/sandbox2:comms",
|
||||
|
@ -70,7 +65,7 @@ cc_binary(
|
|||
|
||||
cc_binary(
|
||||
name = "ipc",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["ipc.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
deps = [
|
||||
|
@ -81,51 +76,42 @@ cc_binary(
|
|||
],
|
||||
)
|
||||
|
||||
# security: disable=cc-static-no-pie
|
||||
cc_binary(
|
||||
name = "malloc_system",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["malloc.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = FULLY_STATIC_FEATURES,
|
||||
linkstatic = 1,
|
||||
features = ["fully_static_link"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "minimal_dynamic",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["minimal.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
)
|
||||
|
||||
# security: disable=cc-static-no-pie
|
||||
cc_binary(
|
||||
name = "minimal",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["minimal.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = FULLY_STATIC_FEATURES,
|
||||
linkstatic = 1,
|
||||
features = ["fully_static_link"],
|
||||
)
|
||||
|
||||
# security: disable=cc-static-no-pie
|
||||
cc_binary(
|
||||
name = "personality",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["personality.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = FULLY_STATIC_FEATURES,
|
||||
linkstatic = 1,
|
||||
features = ["fully_static_link"],
|
||||
)
|
||||
|
||||
# security: disable=cc-static-no-pie
|
||||
cc_binary(
|
||||
name = "pidcomms",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["pidcomms.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = FULLY_STATIC_FEATURES,
|
||||
linkstatic = 1,
|
||||
deps = [
|
||||
"//sandboxed_api/sandbox2:client",
|
||||
"//sandboxed_api/sandbox2:comms",
|
||||
|
@ -133,40 +119,32 @@ cc_binary(
|
|||
],
|
||||
)
|
||||
|
||||
# security: disable=cc-static-no-pie
|
||||
cc_binary(
|
||||
name = "policy",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["policy.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = FULLY_STATIC_FEATURES,
|
||||
linkstatic = 1,
|
||||
features = ["fully_static_link"],
|
||||
deps = ["//sandboxed_api:config"],
|
||||
)
|
||||
|
||||
# security: disable=cc-static-no-pie
|
||||
cc_binary(
|
||||
name = "print_fds",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["print_fds.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = FULLY_STATIC_FEATURES,
|
||||
linkstatic = 1,
|
||||
)
|
||||
|
||||
# security: disable=cc-static-no-pie
|
||||
cc_binary(
|
||||
name = "sanitizer",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["sanitizer.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = FULLY_STATIC_FEATURES,
|
||||
linkstatic = 1,
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "close_fds",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["close_fds.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
deps = [
|
||||
|
@ -177,24 +155,19 @@ cc_binary(
|
|||
],
|
||||
)
|
||||
|
||||
# security: disable=cc-static-no-pie
|
||||
cc_binary(
|
||||
name = "sleep",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["sleep.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = FULLY_STATIC_FEATURES,
|
||||
linkstatic = 1,
|
||||
features = ["fully_static_link"],
|
||||
)
|
||||
|
||||
# security: disable=cc-static-no-pie
|
||||
cc_binary(
|
||||
name = "symbolize",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["symbolize.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = FULLY_STATIC_FEATURES,
|
||||
linkstatic = 1,
|
||||
deps = [
|
||||
"//sandboxed_api/util:raw_logging",
|
||||
"//sandboxed_api/util:temp_file",
|
||||
|
@ -205,7 +178,7 @@ cc_binary(
|
|||
|
||||
cc_binary(
|
||||
name = "tsync",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["tsync.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
deps = [
|
||||
|
@ -216,34 +189,30 @@ cc_binary(
|
|||
|
||||
cc_binary(
|
||||
name = "starve",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["starve.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "hostname",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["hostname.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = FULLY_STATIC_FEATURES,
|
||||
linkstatic = 1,
|
||||
features = ["fully_static_link"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "limits",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["limits.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = FULLY_STATIC_FEATURES,
|
||||
linkstatic = 1,
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "namespace",
|
||||
testonly = 1,
|
||||
testonly = True,
|
||||
srcs = ["namespace.cc"],
|
||||
copts = sapi_platform_copts(),
|
||||
features = FULLY_STATIC_FEATURES,
|
||||
linkstatic = 1,
|
||||
features = ["fully_static_link"],
|
||||
)
|
||||
|
|
|
@ -12,12 +12,6 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
if(SAPI_LIB_TYPE STREQUAL "STATIC")
|
||||
set(_sandbox2_linkopts -static)
|
||||
else()
|
||||
set(_sandbox2_linkopts ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:abort
|
||||
add_executable(sandbox2_testcase_abort
|
||||
abort.cc
|
||||
|
@ -40,7 +34,8 @@ set_target_properties(sandbox2_testcase_add_policy_on_syscalls PROPERTIES
|
|||
OUTPUT_NAME add_policy_on_syscalls
|
||||
)
|
||||
target_link_libraries(sandbox2_testcase_add_policy_on_syscalls PRIVATE
|
||||
${_sandbox2_linkopts}
|
||||
-static
|
||||
sapi::base
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:buffer
|
||||
|
@ -56,7 +51,6 @@ target_link_libraries(sandbox2_testcase_buffer PRIVATE
|
|||
sandbox2::buffer
|
||||
sandbox2::comms
|
||||
sapi::base
|
||||
${_sandbox2_linkopts}
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:ipc
|
||||
|
@ -85,8 +79,8 @@ set_target_properties(sandbox2_testcase_malloc_system PROPERTIES
|
|||
OUTPUT_NAME malloc_system
|
||||
)
|
||||
target_link_libraries(sandbox2_testcase_malloc_system PRIVATE
|
||||
-static
|
||||
sapi::base
|
||||
${_sandbox2_linkopts}
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:minimal_dynamic
|
||||
|
@ -111,8 +105,8 @@ set_target_properties(sandbox2_testcase_minimal PROPERTIES
|
|||
OUTPUT_NAME minimal
|
||||
)
|
||||
target_link_libraries(sandbox2_testcase_minimal PRIVATE
|
||||
-static
|
||||
sapi::base
|
||||
${_sandbox2_linkopts}
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:personality
|
||||
|
@ -125,8 +119,8 @@ set_target_properties(sandbox2_testcase_personality PROPERTIES
|
|||
OUTPUT_NAME personality
|
||||
)
|
||||
target_link_libraries(sandbox2_testcase_personality PRIVATE
|
||||
-static
|
||||
sapi::base
|
||||
${_sandbox2_linkopts}
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:pidcomms
|
||||
|
@ -142,7 +136,6 @@ target_link_libraries(sandbox2_testcase_pidcomms PRIVATE
|
|||
sandbox2::comms
|
||||
sapi::base
|
||||
sapi::raw_logging
|
||||
${_sandbox2_linkopts}
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:policy
|
||||
|
@ -154,9 +147,9 @@ set_target_properties(sandbox2_testcase_policy PROPERTIES
|
|||
OUTPUT_NAME policy
|
||||
)
|
||||
target_link_libraries(sandbox2_testcase_policy PRIVATE
|
||||
-static
|
||||
sapi::base
|
||||
sapi::config
|
||||
${_sandbox2_linkopts}
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:print_fds
|
||||
|
@ -169,7 +162,6 @@ set_target_properties(sandbox2_testcase_print_fds PROPERTIES
|
|||
)
|
||||
target_link_libraries(sandbox2_testcase_print_fds PRIVATE
|
||||
sapi::base
|
||||
${_sandbox2_linkopts}
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:sanitizer
|
||||
|
@ -182,7 +174,6 @@ set_target_properties(sandbox2_testcase_sanitizer PROPERTIES
|
|||
)
|
||||
target_link_libraries(sandbox2_testcase_sanitizer PRIVATE
|
||||
sapi::base
|
||||
${_sandbox2_linkopts}
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:close_fds
|
||||
|
@ -195,7 +186,6 @@ set_target_properties(sandbox2_testcase_close_fds PROPERTIES
|
|||
)
|
||||
target_link_libraries(sandbox2_testcase_close_fds PRIVATE
|
||||
sapi::base
|
||||
${_sandbox2_linkopts}
|
||||
absl::strings
|
||||
absl::flat_hash_set
|
||||
glog::glog
|
||||
|
@ -212,8 +202,8 @@ set_target_properties(sandbox2_testcase_sleep PROPERTIES
|
|||
OUTPUT_NAME sleep
|
||||
)
|
||||
target_link_libraries(sandbox2_testcase_sleep PRIVATE
|
||||
-static
|
||||
sapi::base
|
||||
${_sandbox2_linkopts}
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:symbolize
|
||||
|
@ -231,7 +221,6 @@ target_link_libraries(sandbox2_testcase_symbolize PRIVATE
|
|||
sapi::strerror
|
||||
sapi::base
|
||||
sapi::raw_logging
|
||||
${_sandbox2_linkopts}
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:starve
|
||||
|
@ -246,7 +235,6 @@ target_link_libraries(sandbox2_testcase_starve PRIVATE
|
|||
sapi::base
|
||||
)
|
||||
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:tsync
|
||||
add_executable(sandbox2_testcase_tsync
|
||||
tsync.cc
|
||||
|
@ -259,7 +247,6 @@ target_link_libraries(sandbox2_testcase_tsync PRIVATE
|
|||
sandbox2::client
|
||||
sandbox2::comms
|
||||
sapi::base
|
||||
${_sandbox2_linkopts}
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:hostname
|
||||
|
@ -271,8 +258,8 @@ set_target_properties(sandbox2_testcase_hostname PROPERTIES
|
|||
OUTPUT_NAME hostname
|
||||
)
|
||||
target_link_libraries(sandbox2_testcase_hostname PRIVATE
|
||||
-static
|
||||
sapi::base
|
||||
${_sandbox2_linkopts}
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:limits
|
||||
|
@ -285,7 +272,6 @@ set_target_properties(sandbox2_testcase_limits PROPERTIES
|
|||
)
|
||||
target_link_libraries(sandbox2_testcase_limits PRIVATE
|
||||
sapi::base
|
||||
${_sandbox2_linkopts}
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2/testcases:namespace
|
||||
|
@ -297,6 +283,6 @@ set_target_properties(sandbox2_testcase_namespace PROPERTIES
|
|||
OUTPUT_NAME namespace
|
||||
)
|
||||
target_link_libraries(sandbox2_testcase_namespace PRIVATE
|
||||
-static
|
||||
sapi::base
|
||||
${_sandbox2_linkopts}
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue
Block a user