Avoid sanitizer macros use Abseil's where necessary

Using C++17 means we can get rid of many `#ifdef`s by using `if constexpr`.
This way, we ensure that both branches compile and still retain zero runtime
overhead.

Note that open source builds of Sandboxed API do not ship with sanitizer
configurations yet. This will be added in follow-up changes.

PiperOrigin-RevId: 354932160
Change-Id: I3678dffc47ea873919f0a8c01f3a7d999fc29a5b
This commit is contained in:
Christian Blichmann 2021-02-01 07:10:43 -08:00 committed by Copybara-Service
parent 6dcef3d5c9
commit 55a8373ec3
25 changed files with 200 additions and 189 deletions

View File

@ -73,18 +73,17 @@ cc_library(
copts = sapi_platform_copts(),
visibility = ["//visibility:public"],
deps = [
":config",
":embed_file",
":vars",
"//sandboxed_api/sandbox2",
"//sandboxed_api/sandbox2:client",
"//sandboxed_api/sandbox2:comms",
"//sandboxed_api/sandbox2:util",
"//sandboxed_api/sandbox2/util:bpf_helper",
"//sandboxed_api/util:file_base",
"//sandboxed_api/util:fileops",
"//sandboxed_api/util:runfiles",
"//sandboxed_api/util:status",
"//sandboxed_api/util:strerror",
"@com_google_absl//absl/base",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
@ -176,6 +175,7 @@ cc_library(
visibility = ["//visibility:public"],
deps = [
":call",
":config",
":lenval_core",
":proto_arg_cc_proto",
":vars",
@ -184,6 +184,7 @@ cc_library(
"//sandboxed_api/sandbox2:forkingclient",
"//sandboxed_api/sandbox2:logsink",
"//sandboxed_api/util:flags",
"@com_google_absl//absl/base:dynamic_annotations",
"@com_google_absl//absl/strings",
"@com_google_glog//:glog",
"@com_google_protobuf//:protobuf",
@ -198,6 +199,7 @@ cc_test(
tags = ["local"],
deps = [
":sapi",
":testing",
"//sandboxed_api/examples/stringop/lib:stringop-sapi",
"//sandboxed_api/examples/stringop/lib:stringop_params_cc_proto",
"//sandboxed_api/examples/sum/lib:sum-sapi",

View File

@ -172,6 +172,7 @@ add_library(sapi_client ${SAPI_LIB_TYPE}
add_library(sapi::client ALIAS sapi_client)
target_link_libraries(sapi_client
PRIVATE absl::core_headers
absl::dynamic_annotations
absl::strings
libffi::libffi
sandbox2::client
@ -189,6 +190,18 @@ target_link_libraries(sapi_client
)
if(SAPI_ENABLE_TESTS AND NOT CMAKE_CROSSCOMPILING)
# sandboxed_api:testing
add_library(sapi_testing ${SAPI_LIB_TYPE}
testing.cc
testing.h
)
add_library(sapi::testing ALIAS sapi_testing)
target_link_libraries(sapi_testing PRIVATE
absl::strings
sapi::file_base
sapi::base
)
# sandboxed_api:sapi_test
add_executable(sapi_test
sapi_test.cc
@ -206,21 +219,9 @@ if(SAPI_ENABLE_TESTS AND NOT CMAKE_CROSSCOMPILING)
sapi::stringop_sapi
sapi::sum_sapi
sapi::test_main
sapi::testing
)
gtest_discover_tests_xcompile(sapi_test)
# sandboxed_api:testing
add_library(sapi_testing ${SAPI_LIB_TYPE}
testing.cc
testing.h
)
add_library(sapi::testing ALIAS sapi_testing)
target_link_libraries(sapi_testing PRIVATE
absl::strings
sapi::file_base
sapi::base
)
endif()
# Install headers and libraries, excluding tools, tests and examples

View File

@ -78,14 +78,14 @@ struct FuncCall {
struct FuncRet {
// Return type:
v::Type ret_type;
v::Type ret_type = v::Type::kVoid;
// Return value.
union {
uintptr_t int_val;
uintptr_t int_val = 0;
long double float_val;
};
// Status of the operation: success/failure.
bool success;
bool success = false;
};
} // namespace sapi

View File

@ -25,9 +25,11 @@
#include <glog/logging.h>
#include "google/protobuf/descriptor.h"
#include "google/protobuf/message.h"
#include "absl/base/dynamic_annotations.h"
#include "sandboxed_api/util/flag.h"
#include "absl/strings/str_cat.h"
#include "sandboxed_api/call.h"
#include "sandboxed_api/config.h"
#include "sandboxed_api/lenval_core.h"
#include "sandboxed_api/proto_arg.pb.h"
#include "sandboxed_api/sandbox2/comms.h"
@ -35,10 +37,6 @@
#include "sandboxed_api/sandbox2/logsink.h"
#include "sandboxed_api/vars.h"
#ifdef MEMORY_SANITIZER
#include <sanitizer/allocator_interface.h>
#endif
#include <ffi.h>
#include <ffitarget.h>
@ -232,15 +230,14 @@ void HandleCallMsg(const FuncCall& call, FuncRet* ret) {
void HandleAllocMsg(const size_t size, FuncRet* ret) {
VLOG(1) << "HandleAllocMsg: size=" << size;
ret->ret_type = v::Type::kPointer;
#ifdef MEMORY_SANITIZER
const void* allocated = malloc(size);
// Memory is copied to the pointer using an API that the memory sanitizer
// is blind to (process_vm_writev). Initialize the memory here so that
// the sandboxed code can still be tested with the memory sanitizer.
ret->int_val = reinterpret_cast<uintptr_t>(calloc(1, size));
#else
ret->int_val = reinterpret_cast<uintptr_t>(malloc(size));
#endif
// is blind to (process_vm_writev). Mark the memory as initialized here, so
// that the sandboxed code can still be tested using MSAN.
ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(allocated, size);
ret->ret_type = v::Type::kPointer;
ret->int_val = reinterpret_cast<uintptr_t>(allocated);
ret->success = true;
}
@ -248,23 +245,16 @@ void HandleAllocMsg(const size_t size, FuncRet* ret) {
void HandleReallocMsg(uintptr_t ptr, size_t size, FuncRet* ret) {
VLOG(1) << "HandleReallocMsg(" << absl::StrCat(absl::Hex(ptr)) << ", " << size
<< ")";
#ifdef MEMORY_SANITIZER
const size_t orig_size =
__sanitizer_get_allocated_size(reinterpret_cast<const void*>(ptr));
#endif
ret->ret_type = v::Type::kPointer;
ret->int_val =
reinterpret_cast<uintptr_t>(realloc(reinterpret_cast<void*>(ptr), size));
ret->success = true;
#ifdef MEMORY_SANITIZER
const void* reallocated = realloc(reinterpret_cast<void*>(ptr), size);
// Memory is copied to the pointer using an API that the memory sanitizer
// is blind to (process_vm_writev). Initialize the memory here so that
// the sandboxed code can still be tested with the memory sanitizer.
if (orig_size < size && ret->int_val != 0) {
memset(reinterpret_cast<void*>(ret->int_val + orig_size), 0,
size - orig_size);
}
#endif
// is blind to (process_vm_writev). Mark the memory as initialized here, so
// that the sandboxed code can still be tested using MSAN.
ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(reallocated, size);
ret->ret_type = v::Type::kPointer;
ret->int_val = reinterpret_cast<uintptr_t>(reallocated);
ret->success = true;
}
// Handles requests to free memory previously allocated by HandleAllocMsg() and
@ -350,10 +340,11 @@ void ServeRequest(sandbox2::Comms* comms) {
CHECK(comms->RecvTLV(&tag, &bytes));
FuncRet ret{};
ret.ret_type = v::Type::kVoid;
ret.int_val = static_cast<uintptr_t>(Error::kUnset);
ret.success = false;
FuncRet ret = {
.ret_type = v::Type::kVoid,
.int_val = static_cast<uintptr_t>(Error::kUnset),
.success = false,
};
switch (tag) {
case comms::kMsgCall:

View File

@ -92,6 +92,37 @@ static_assert(host_cpu::Architecture() != cpu::kUnknown,
"Host CPU architecture is not supported: One of x86-64, POWER64 "
"(little endian), Arm or AArch64 is required.");
namespace sanitizers {
constexpr bool IsMSan() {
#ifdef ABSL_HAVE_MEMORY_SANITIZER
return true;
#else
return false;
#endif
}
constexpr bool IsTSan() {
#ifdef ABSL_HAVE_THREAD_SANITIZER
return true;
#else
return false;
#endif
}
constexpr bool IsASan() {
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
return true;
#else
return false;
#endif
}
// Returns whether any of the sanitizers is enabled.
constexpr bool IsAny() { return IsMSan() || IsTSan() || IsASan(); }
} // namespace sanitizers
} // namespace sapi
#endif // SANDBOXED_API_CONFIG_H_

View File

@ -31,14 +31,14 @@
#include "sandboxed_api/util/status_matchers.h"
#include "sandboxed_api/vars.h"
namespace {
using ::sapi::IsOk;
using ::testing::Eq;
using ::testing::Ne;
using ::testing::SizeIs;
using ::testing::StrEq;
namespace {
// Tests using a simple transaction (and function pointers):
TEST(StringopTest, ProtobufStringDuplication) {
sapi::BasicTransaction st(absl::make_unique<StringopSapiSandbox>());

View File

@ -31,6 +31,7 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/time/time.h"
#include "sandboxed_api/config.h"
#include "sandboxed_api/embed_file.h"
#include "sandboxed_api/rpcchannel.h"
#include "sandboxed_api/sandbox2/executor.h"
@ -92,12 +93,11 @@ void InitDefaultPolicyBuilder(sandbox2::PolicyBuilder* builder) {
})
.AddFile("/etc/localtime")
.AddTmpfs("/tmp", 1ULL << 30 /* 1GiB tmpfs (max size) */);
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
defined(THREAD_SANITIZER)
LOG(WARNING) << "Allowing additional calls to support the LLVM "
<< "(ASAN/MSAN/TSAN) sanitizer";
builder->AllowLlvmSanitizers();
#endif
if constexpr (sanitizers::IsAny()) {
LOG(WARNING) << "Allowing additional calls to support the LLVM "
<< "(ASAN/MSAN/TSAN) sanitizer";
builder->AllowLlvmSanitizers();
}
}
void Sandbox::Terminate(bool attempt_graceful_exit) {

View File

@ -604,7 +604,9 @@ cc_library(
"//sandboxed_api/util:status",
"//sandboxed_api/util:status_cc_proto",
"//sandboxed_api/util:strerror",
"@com_google_absl//absl/base:config",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/base:dynamic_annotations",
"@com_google_absl//absl/memory",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
@ -829,6 +831,7 @@ cc_test(
deps = [
":comms",
":sandbox2",
"//sandboxed_api:config",
"//sandboxed_api:testing",
"//sandboxed_api/sandbox2/util:bpf_helper",
"//sandboxed_api/util:status_matchers",

View File

@ -34,6 +34,8 @@
#include <functional>
#include "google/protobuf/message.h"
#include "absl/base/config.h"
#include "absl/base/dynamic_annotations.h"
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
@ -45,10 +47,6 @@
#include "sandboxed_api/util/status.h"
#include "sandboxed_api/util/strerror.h"
#ifdef MEMORY_SANITIZER
#include "base/dynamic_annotations.h"
#endif
namespace sandbox2 {
// Future extension point used to mark code sections that invoke syscalls that
@ -241,13 +239,11 @@ bool Comms::SendTLV(uint32_t tag, size_t length, const void* value) {
if (!Send(&length, sizeof(length))) {
return false;
}
if (length > 0) {
if (!Send(value, length)) {
return false;
}
if (length > 0 && !Send(value, length)) {
return false;
}
return true;
}
return true;
}
bool Comms::RecvString(std::string* v) {
@ -358,9 +354,7 @@ bool Comms::RecvFD(int* fd) {
// msg struct has been fully populated. Apparently MSAN is not aware of
// syscall(__NR_recvmsg) semantics so we need to suppress the error (here and
// everywhere below).
#ifdef MEMORY_SANITIZER
ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(&tlv, sizeof(tlv));
#endif
if (tlv.tag != kTagFd) {
SAPI_RAW_LOG(ERROR, "Expected (kTagFD: 0x%x), got: 0x%u", kTagFd, tlv.tag);
@ -368,9 +362,7 @@ bool Comms::RecvFD(int* fd) {
}
cmsg = CMSG_FIRSTHDR(&msg);
#ifdef MEMORY_SANITIZER
ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(cmsg, sizeof(cmsghdr));
#endif
while (cmsg) {
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
@ -381,9 +373,7 @@ bool Comms::RecvFD(int* fd) {
}
int* fds = reinterpret_cast<int*>(CMSG_DATA(cmsg));
*fd = fds[0];
#ifdef MEMORY_SANITIZER
ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(fd, sizeof(int));
#endif
return true;
}
cmsg = CMSG_NXTHDR(&msg, cmsg);

View File

@ -30,6 +30,7 @@ cc_binary(
copts = sapi_platform_copts(),
data = [":crc4bin"],
deps = [
"//sandboxed_api:config",
"//sandboxed_api/sandbox2",
"//sandboxed_api/sandbox2:comms",
"//sandboxed_api/sandbox2/util:bpf_helper",

View File

@ -30,6 +30,7 @@
#include <glog/logging.h>
#include "sandboxed_api/util/flag.h"
#include "absl/memory/memory.h"
#include "sandboxed_api/config.h"
#include "sandboxed_api/sandbox2/comms.h"
#include "sandboxed_api/sandbox2/executor.h"
#include "sandboxed_api/sandbox2/limits.h"
@ -40,7 +41,7 @@
#include "sandboxed_api/sandbox2/util/bpf_helper.h"
#include "sandboxed_api/util/runfiles.h"
using std::string;
using std::string; // gflags <-> Abseil Flags
ABSL_FLAG(string, input, "", "Input to calculate CRC4 of.");
ABSL_FLAG(bool, call_syscall_not_allowed, false,
@ -49,21 +50,21 @@ ABSL_FLAG(bool, call_syscall_not_allowed, false,
namespace {
std::unique_ptr<sandbox2::Policy> GetPolicy() {
return sandbox2::PolicyBuilder()
.DisableNamespaces()
.AllowExit()
.AddPolicyOnSyscalls(
{__NR_read, __NR_write, __NR_close},
{ARG_32(0), JEQ32(sandbox2::Comms::kSandbox2ClientCommsFD, ALLOW)})
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
defined(THREAD_SANITIZER)
.AllowSyscall(__NR_mmap)
#endif
.BuildOrDie();
sandbox2::PolicyBuilder builder;
builder.DisableNamespaces().AllowExit().AddPolicyOnSyscalls(
{__NR_read, __NR_write, __NR_close},
{
ARG_32(0),
JEQ32(sandbox2::Comms::kSandbox2ClientCommsFD, ALLOW),
});
if constexpr (sapi::sanitizers::IsAny()) {
builder.AllowSyscall(__NR_mmap);
}
return builder.BuildOrDie();
}
bool SandboxedCRC4(sandbox2::Comms* comms, uint32_t* crc4) {
std::string input(absl::GetFlag(FLAGS_input));
const std::string input = absl::GetFlag(FLAGS_input);
const uint8_t* buf = reinterpret_cast<const uint8_t*>(input.data());
size_t buf_size = input.size();

View File

@ -27,6 +27,7 @@ cc_binary(
copts = sapi_platform_copts(),
data = [":custom_fork_bin"],
deps = [
"//sandboxed_api:config",
"//sandboxed_api/sandbox2",
"//sandboxed_api/sandbox2:comms",
"//sandboxed_api/sandbox2:forkserver",

View File

@ -26,6 +26,7 @@
#include <glog/logging.h>
#include "sandboxed_api/util/flag.h"
#include "absl/memory/memory.h"
#include "sandboxed_api/config.h"
#include "sandboxed_api/sandbox2/comms.h"
#include "sandboxed_api/sandbox2/executor.h"
#include "sandboxed_api/sandbox2/forkserver.h"
@ -37,9 +38,10 @@
#include "sandboxed_api/util/runfiles.h"
std::unique_ptr<sandbox2::Policy> GetPolicy() {
return sandbox2::PolicyBuilder()
// The most frequent syscall should go first in this sequence (to make it
// fast).
sandbox2::PolicyBuilder builder;
builder
// The most frequent syscall should go first in this
// sequence (to make it fast).
.AllowRead()
.AllowWrite()
.AllowExit()
@ -47,15 +49,14 @@ std::unique_ptr<sandbox2::Policy> GetPolicy() {
.AllowSyscalls({
__NR_close, __NR_getpid,
#if defined(__NR_arch_prctl)
// Not defined with every CPU architecture in Prod.
// Not defined with every CPU architecture in prod.
__NR_arch_prctl,
#endif // defined(__NR_arch_prctl)
})
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
defined(THREAD_SANITIZER)
.AllowMmap()
#endif
.BuildOrDie();
});
if constexpr (sapi::sanitizers::IsAny()) {
builder.AllowMmap();
}
return builder.BuildOrDie();
}
static int SandboxIteration(sandbox2::ForkClient* fork_client, int32_t i) {
@ -68,14 +69,9 @@ static int SandboxIteration(sandbox2::ForkClient* fork_client, int32_t i) {
->limits()
// Remove restrictions on the size of address-space of sandboxed
// processes. Here, it's 1GiB.
->set_rlimit_as(
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
defined(THREAD_SANITIZER)
RLIM64_INFINITY
#else
1ULL << 30 // 1GiB
#endif
)
->set_rlimit_as(sapi::sanitizers::IsAny() ? RLIM64_INFINITY
: 1ULL << 30 // 1GiB
)
// Kill sandboxed processes with a signal (SIGXFSZ) if it writes more than
// these many bytes to the file-system (including logs in prod, which
// write to files STDOUT and STDERR).
@ -84,15 +80,12 @@ static int SandboxIteration(sandbox2::ForkClient* fork_client, int32_t i) {
.set_rlimit_cpu(10 /* CPU-seconds */)
.set_walltime_limit(absl::Seconds(5));
auto* comms = executor->ipc()->comms();
auto policy = GetPolicy();
sandbox2::Sandbox2 s2(std::move(executor), std::move(policy));
sandbox2::Sandbox2 s2(std::move(executor), GetPolicy());
// Let the sandboxee run (asynchronously).
CHECK(s2.RunAsync());
// Send integer, which will be returned as the sandboxee's exit code.
CHECK(comms->SendInt32(i));
CHECK(s2.comms()->SendInt32(i));
auto result = s2.AwaitResult();
LOG(INFO) << "Final execution status of PID " << s2.GetPid() << ": "
@ -111,10 +104,9 @@ int main(int argc, char** argv) {
// This test is incompatible with sanitizers.
// The `SKIP_SANITIZERS_AND_COVERAGE` macro won't work for us here since we
// need to return something.
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
defined(THREAD_SANITIZER)
return EXIT_SUCCESS;
#endif
if constexpr (sapi::sanitizers::IsAny()) {
return EXIT_SUCCESS;
}
// Start a custom fork-server (via sandbox2::Executor).
// Note: In your own code, use sapi::GetDataDependencyFilePath() instead.

View File

@ -29,6 +29,7 @@ cc_binary(
copts = sapi_platform_copts(),
data = [":network_bin"],
deps = [
"//sandboxed_api:config",
"//sandboxed_api/sandbox2",
"//sandboxed_api/sandbox2:comms",
"//sandboxed_api/sandbox2/util:bpf_helper",

View File

@ -30,6 +30,7 @@
#include <glog/logging.h>
#include "absl/base/macros.h"
#include "sandboxed_api/util/flag.h"
#include "sandboxed_api/config.h"
#include "sandboxed_api/sandbox2/comms.h"
#include "sandboxed_api/sandbox2/executor.h"
#include "sandboxed_api/sandbox2/policy.h"
@ -143,7 +144,7 @@ int ConnectToServer(int port) {
}
bool HandleSandboxee(sandbox2::Comms* comms, int port) {
// connect to the server and pass the file descriptor to sandboxee.
// Connect to the server and pass the file descriptor to sandboxee.
int client = ConnectToServer(port);
if (client <= 0) {
LOG(ERROR) << "connect_to_server() failed";
@ -165,10 +166,9 @@ int main(int argc, char** argv) {
// This test is incompatible with sanitizers.
// The `SKIP_SANITIZERS_AND_COVERAGE` macro won't work for us here since we
// need to return something.
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
defined(THREAD_SANITIZER)
return EXIT_SUCCESS;
#endif
if constexpr (sapi::sanitizers::IsAny()) {
return EXIT_SUCCESS;
}
if (getenv("COVERAGE") != nullptr) {
return EXIT_SUCCESS;
}

View File

@ -25,6 +25,7 @@ cc_binary(
copts = sapi_platform_copts(),
data = [":networkproxy_bin"],
deps = [
"//sandboxed_api:config",
"//sandboxed_api/sandbox2",
"//sandboxed_api/sandbox2:comms",
"//sandboxed_api/sandbox2/util:bpf_helper",

View File

@ -18,6 +18,7 @@
#include <glog/logging.h>
#include "absl/base/macros.h"
#include "sandboxed_api/util/flag.h"
#include "sandboxed_api/config.h"
#include "sandboxed_api/sandbox2/comms.h"
#include "sandboxed_api/sandbox2/executor.h"
#include "sandboxed_api/sandbox2/policy.h"
@ -35,8 +36,8 @@ constexpr char kSandboxeePath[] =
"sandbox2/examples/network_proxy/networkproxy_bin";
std::unique_ptr<sandbox2::Policy> GetPolicy(absl::string_view sandboxee_path) {
sandbox2::PolicyBuilder policy;
policy.AllowExit()
sandbox2::PolicyBuilder builder;
builder.AllowExit()
.AllowMmap()
.AllowRead()
.AllowWrite()
@ -49,11 +50,11 @@ std::unique_ptr<sandbox2::Policy> GetPolicy(absl::string_view sandboxee_path) {
.AllowTcMalloc()
.AddLibrariesForBinary(sandboxee_path);
if (absl::GetFlag(FLAGS_connect_with_handler)) {
policy.AddNetworkProxyHandlerPolicy();
builder.AddNetworkProxyHandlerPolicy();
} else {
policy.AddNetworkProxyPolicy();
builder.AddNetworkProxyPolicy();
}
return policy.AllowIPv6("::1").BuildOrDie();
return builder.AllowIPv6("::1").BuildOrDie();
}
void Server(int port) {
@ -115,10 +116,9 @@ int main(int argc, char** argv) {
// This test is incompatible with sanitizers.
// The `SKIP_SANITIZERS_AND_COVERAGE` macro won't work for us here since we
// need to return something.
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
defined(THREAD_SANITIZER)
return EXIT_SUCCESS;
#endif
if constexpr (sapi::sanitizers::IsAny()) {
return EXIT_SUCCESS;
}
if (getenv("COVERAGE") != nullptr) {
return EXIT_SUCCESS;
}

View File

@ -30,6 +30,7 @@ cc_binary(
copts = sapi_platform_copts(),
data = [":static_bin"],
deps = [
"//sandboxed_api:config",
"//sandboxed_api/sandbox2",
"//sandboxed_api/sandbox2/util:bpf_helper",
"//sandboxed_api/util:flags",

View File

@ -30,6 +30,7 @@
#include <glog/logging.h>
#include "sandboxed_api/util/flag.h"
#include "absl/memory/memory.h"
#include "sandboxed_api/config.h"
#include "sandboxed_api/sandbox2/executor.h"
#include "sandboxed_api/sandbox2/limits.h"
#include "sandboxed_api/sandbox2/policy.h"
@ -101,10 +102,9 @@ int main(int argc, char** argv) {
// This test is incompatible with sanitizers.
// The `SKIP_SANITIZERS_AND_COVERAGE` macro won't work for us here since we
// need to return something.
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
defined(THREAD_SANITIZER)
return EXIT_SUCCESS;
#endif
if constexpr (sapi::sanitizers::IsAny()) {
return EXIT_SUCCESS;
}
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);

View File

@ -193,20 +193,19 @@ PolicyBuilder& PolicyBuilder::AllowSystemMalloc() {
}
PolicyBuilder& PolicyBuilder::AllowLlvmSanitizers() {
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
defined(THREAD_SANITIZER)
AddPolicyOnSyscall(__NR_madvise, {
ARG_32(2),
JEQ32(MADV_DONTDUMP, ALLOW),
JEQ32(MADV_NOHUGEPAGE, ALLOW),
});
// Sanitizers read from /proc. For example:
// https://github.com/llvm-mirror/compiler-rt/blob/69445f095c22aac2388f939bedebf224a6efcdaf/lib/sanitizer_common/sanitizer_linux.cpp#L1101
AddDirectory("/proc");
#endif
#if defined(ADDRESS_SANITIZER)
AllowSyscall(__NR_sigaltstack);
#endif
if constexpr (sapi::sanitizers::IsAny()) {
AddPolicyOnSyscall(__NR_madvise, {
ARG_32(2),
JEQ32(MADV_DONTDUMP, ALLOW),
JEQ32(MADV_NOHUGEPAGE, ALLOW),
});
// Sanitizers read from /proc. For example:
// https://github.com/llvm-mirror/compiler-rt/blob/69445f095c22aac2388f939bedebf224a6efcdaf/lib/sanitizer_common/sanitizer_linux.cpp#L1101
AddDirectory("/proc");
}
if constexpr (sapi::sanitizers::IsASan()) {
AllowSyscall(__NR_sigaltstack);
}
return *this;
}

View File

@ -29,6 +29,7 @@
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "sandboxed_api/config.h"
#include "sandboxed_api/sandbox2/comms.h"
#include "sandboxed_api/sandbox2/executor.h"
#include "sandboxed_api/sandbox2/ipc.h"
@ -166,10 +167,9 @@ std::string PolicyBuilderTest::Run(std::vector<std::string> args,
}
auto executor = absl::make_unique<sandbox2::Executor>(args[0], args);
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
defined(THREAD_SANITIZER)
executor->limits()->set_rlimit_as(RLIM64_INFINITY);
#endif
if constexpr (sapi::sanitizers::IsAny()) {
executor->limits()->set_rlimit_as(RLIM64_INFINITY);
}
int fd1 = executor->ipc()->ReceiveFd(STDOUT_FILENO);
sandbox2::Sandbox2 s2(std::move(executor), builder.BuildOrDie());

View File

@ -18,6 +18,7 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "sandboxed_api/config.h"
#include "sandboxed_api/sandbox2/syscall.h"
#include "sandboxed_api/sandbox2/util.h"
@ -109,21 +110,20 @@ std::string Result::ToString() const {
result =
absl::StrCat("<UNKNOWN>(", final_status(), ") Code: ", reason_code());
}
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
defined(THREAD_SANITIZER)
absl::StrAppend(&result,
" - Warning: this executor is built with ASAN, "
"MSAN or TSAN, chances are the sandboxee too, which is "
"incompatible with sandboxing.");
#else
if (
getenv("COVERAGE") != nullptr) {
absl::StrAppend(&result,
" - Warning: this executor is built with coverage "
"enabled, chances are the sandboxee too, which is "
"incompatible with sandboxing.");
if constexpr (sapi::sanitizers::IsAny()) {
absl::StrAppend(
&result,
" - Warning: this executor is built with ASAN, MSAN or TSAN, chances "
"are the sandboxee is too, which is incompatible with sandboxing.");
} else {
if (
getenv("COVERAGE") != nullptr) {
absl::StrAppend(
&result,
" - Warning: this executor is built with coverage enabled, chances "
"are the sandboxee too, which is incompatible with sandboxing.");
}
}
#endif
return result;
}

View File

@ -291,21 +291,13 @@ std::vector<std::string> GetStackTrace(const Regs* regs, const Mounts& mounts) {
return {"[ERROR (noregs)]"};
}
#if defined(THREAD_SANITIZER) || defined(ADDRESS_SANITIZER) || \
defined(MEMORY_SANITIZER)
constexpr bool kSanitizerEnabled = true;
#else
constexpr bool kSanitizerEnabled = false;
#endif
const bool coverage_enabled =
getenv("COVERAGE");
// Show a warning if sandboxed libunwind is requested but we're running in
// an ASAN / coverage build (= we can't use sandboxed libunwind).
if (absl::GetFlag(FLAGS_sandbox_libunwind_crash_handler) &&
(kSanitizerEnabled || coverage_enabled)) {
LOG_IF(WARNING, kSanitizerEnabled)
// an ASAN/coverage build (= we can't use sandboxed libunwind).
if (const bool coverage_enabled =
getenv("COVERAGE") != nullptr;
absl::GetFlag(FLAGS_sandbox_libunwind_crash_handler) &&
(sapi::sanitizers::IsAny() || coverage_enabled)) {
LOG_IF(WARNING, sapi::sanitizers::IsAny())
<< "Sanitizer build, using non-sandboxed libunwind";
LOG_IF(WARNING, coverage_enabled)
<< "Coverage build, using non-sandboxed libunwind";

View File

@ -25,17 +25,18 @@
#include "sandboxed_api/examples/sum/lib/sandbox.h"
#include "sandboxed_api/examples/sum/lib/sum-sapi.sapi.h"
#include "sandboxed_api/examples/sum/lib/sum-sapi_embed.h"
#include "sandboxed_api/testing.h"
#include "sandboxed_api/transaction.h"
#include "sandboxed_api/util/status_matchers.h"
namespace sapi {
namespace {
using ::sapi::IsOk;
using ::sapi::StatusIs;
using ::testing::Eq;
using ::testing::HasSubstr;
namespace sapi {
namespace {
// Functions that will be used during the benchmarks:
// Function causing no load in the sandboxee.
@ -134,7 +135,9 @@ void BenchmarkIntDataSynchronization(benchmark::State& state) {
BENCHMARK(BenchmarkIntDataSynchronization);
// Test whether stack trace generation works.
TEST(SAPITest, HasStackTraces) {
TEST(SapiTest, HasStackTraces) {
SKIP_SANITIZERS_AND_COVERAGE;
auto sandbox = absl::make_unique<StringopSandbox>();
ASSERT_THAT(sandbox->Init(), IsOk());
StringopApi api(sandbox.get());

View File

@ -40,16 +40,17 @@
//
// The downside of this approach is that no coverage will be collected.
// To still have coverage, pre-compile sandboxees and add them as test data,
// then no need to skip tests.
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
defined(THREAD_SANITIZER)
// then there will be no need to skip tests.
#if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER)
#define SKIP_SANITIZERS_AND_COVERAGE return
#else
#define SKIP_SANITIZERS_AND_COVERAGE \
do { \
if (getenv("COVERAGE") != nullptr) { \
return; \
} \
#define SAPI_BUILDDATA_COVERAGE_ENABLED false
#define SKIP_SANITIZERS_AND_COVERAGE \
do { \
if (SAPI_BUILDDATA_COVERAGE_ENABLED || getenv("COVERAGE") != nullptr) { \
return; \
} \
} while (0)
#endif