mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
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:
parent
6dcef3d5c9
commit
55a8373ec3
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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>());
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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]);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user