mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Run more tests with coverage enabled
PiperOrigin-RevId: 561575508 Change-Id: Ifc9a678b6a6cbcd892a1f8710b941514eb1d9764
This commit is contained in:
parent
47c868e6b1
commit
f715bd8ba9
|
@ -23,9 +23,12 @@ exports_files(["LICENSE"])
|
|||
|
||||
cc_library(
|
||||
name = "config",
|
||||
srcs = ["config.cc"],
|
||||
hdrs = ["config.h"],
|
||||
copts = sapi_platform_copts(),
|
||||
deps = ["@com_google_absl//absl/base:config"],
|
||||
deps = [
|
||||
"@com_google_absl//absl/base:config",
|
||||
],
|
||||
)
|
||||
|
||||
sapi_proto_library(
|
||||
|
|
|
@ -22,12 +22,13 @@ add_subdirectory(examples)
|
|||
|
||||
# sandboxed_api:config
|
||||
add_library(sapi_config ${SAPI_LIB_TYPE}
|
||||
config.cc
|
||||
config.h
|
||||
)
|
||||
add_library(sapi::config ALIAS sapi_config)
|
||||
target_link_libraries(sapi_config
|
||||
PRIVATE sapi::base
|
||||
INTERFACE absl::config
|
||||
PUBLIC absl::config
|
||||
)
|
||||
|
||||
# sandboxed_api:proto_arg
|
||||
|
|
11
sandboxed_api/config.cc
Normal file
11
sandboxed_api/config.cc
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include "sandboxed_api/config.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace sapi {
|
||||
|
||||
bool IsCoverageRun() {
|
||||
return getenv("COVERAGE") != nullptr;
|
||||
}
|
||||
|
||||
} // namespace sapi
|
|
@ -17,9 +17,8 @@
|
|||
|
||||
#include <features.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/config.h" // IWYU pragma: keep
|
||||
|
||||
// GCC/Clang define __x86_64__, Visual Studio uses _M_X64
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
|
@ -43,6 +42,9 @@
|
|||
|
||||
namespace sapi {
|
||||
|
||||
// Returns whether the executable running under code coverage.
|
||||
bool IsCoverageRun();
|
||||
|
||||
namespace cpu {
|
||||
|
||||
// CPU architectures known to Sandbox2
|
||||
|
|
|
@ -136,7 +136,7 @@ TEST(PolicyTest, BpfPtracePermissionDenied) {
|
|||
}
|
||||
|
||||
TEST(PolicyTest, IsattyAllowed) {
|
||||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
SKIP_SANITIZERS;
|
||||
sandbox2::PolicyBuilder builder;
|
||||
if constexpr (sapi::host_os::IsAndroid()) {
|
||||
builder.DisableNamespaces().AllowDynamicStartup();
|
||||
|
@ -145,7 +145,8 @@ TEST(PolicyTest, IsattyAllowed) {
|
|||
.AllowExit()
|
||||
.AllowRead()
|
||||
.AllowWrite()
|
||||
.AllowTCGETS();
|
||||
.AllowTCGETS()
|
||||
.AllowLlvmCoverage();
|
||||
const std::string path = GetTestSourcePath("sandbox2/testcases/policy");
|
||||
std::vector<std::string> args = {path, "6"};
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(auto policy, builder.TryBuild());
|
||||
|
@ -155,7 +156,7 @@ TEST(PolicyTest, IsattyAllowed) {
|
|||
ASSERT_THAT(result.final_status(), Eq(Result::OK));
|
||||
}
|
||||
|
||||
std::unique_ptr<Policy> MinimalTestcasePolicy() {
|
||||
std::unique_ptr<Policy> MinimalTestcasePolicy(absl::string_view path = "") {
|
||||
sandbox2::PolicyBuilder builder;
|
||||
|
||||
if constexpr (sapi::host_os::IsAndroid()) {
|
||||
|
@ -163,7 +164,7 @@ std::unique_ptr<Policy> MinimalTestcasePolicy() {
|
|||
builder.DisableNamespaces();
|
||||
}
|
||||
|
||||
builder.AllowStaticStartup().AllowExit();
|
||||
builder.AllowStaticStartup().AllowExit().AllowLlvmCoverage();
|
||||
return builder.BuildOrDie();
|
||||
}
|
||||
|
||||
|
@ -172,10 +173,11 @@ std::unique_ptr<Policy> MinimalTestcasePolicy() {
|
|||
// compile static binaries, and we need to update the policy just above.
|
||||
TEST(MinimalTest, MinimalBinaryWorks) {
|
||||
SKIP_ANDROID;
|
||||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
SKIP_SANITIZERS;
|
||||
const std::string path = GetTestSourcePath("sandbox2/testcases/minimal");
|
||||
std::vector<std::string> args = {path};
|
||||
Sandbox2 s2(std::make_unique<Executor>(path, args), MinimalTestcasePolicy());
|
||||
Sandbox2 s2(std::make_unique<Executor>(path, args),
|
||||
MinimalTestcasePolicy(path));
|
||||
auto result = s2.Run();
|
||||
|
||||
ASSERT_THAT(result.final_status(), Eq(Result::OK));
|
||||
|
@ -184,7 +186,7 @@ TEST(MinimalTest, MinimalBinaryWorks) {
|
|||
|
||||
// Test that we can sandbox a minimal non-static binary returning 0.
|
||||
TEST(MinimalTest, MinimalSharedBinaryWorks) {
|
||||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
SKIP_SANITIZERS;
|
||||
const std::string path =
|
||||
GetTestSourcePath("sandbox2/testcases/minimal_dynamic");
|
||||
std::vector<std::string> args = {path};
|
||||
|
@ -197,7 +199,7 @@ TEST(MinimalTest, MinimalSharedBinaryWorks) {
|
|||
builder.AddLibrariesForBinary(path);
|
||||
}
|
||||
|
||||
builder.AllowDynamicStartup().AllowExit();
|
||||
builder.AllowDynamicStartup().AllowExit().AllowLlvmCoverage();
|
||||
auto policy = builder.BuildOrDie();
|
||||
|
||||
Sandbox2 s2(std::make_unique<Executor>(path, args), std::move(policy));
|
||||
|
@ -209,7 +211,7 @@ TEST(MinimalTest, MinimalSharedBinaryWorks) {
|
|||
|
||||
// Test that the AllowSystemMalloc helper works as expected.
|
||||
TEST(MallocTest, SystemMallocWorks) {
|
||||
SKIP_SANITIZERS_AND_COVERAGE;
|
||||
SKIP_SANITIZERS;
|
||||
const std::string path =
|
||||
GetTestSourcePath("sandbox2/testcases/malloc_system");
|
||||
std::vector<std::string> args = {path};
|
||||
|
@ -224,7 +226,10 @@ TEST(MallocTest, SystemMallocWorks) {
|
|||
});
|
||||
}
|
||||
|
||||
builder.AllowStaticStartup().AllowSystemMalloc().AllowExit();
|
||||
builder.AllowStaticStartup()
|
||||
.AllowSystemMalloc()
|
||||
.AllowExit()
|
||||
.AllowLlvmCoverage();
|
||||
auto policy = builder.BuildOrDie();
|
||||
|
||||
Sandbox2 s2(std::make_unique<Executor>(path, args), std::move(policy));
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <cerrno>
|
||||
#include <csignal>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
|
@ -327,13 +328,16 @@ PolicyBuilder& PolicyBuilder::AllowSystemMalloc() {
|
|||
}
|
||||
|
||||
PolicyBuilder& PolicyBuilder::AllowLlvmSanitizers() {
|
||||
if constexpr (sapi::sanitizers::IsAny()) {
|
||||
if constexpr (!sapi::sanitizers::IsAny()) {
|
||||
return *this;
|
||||
}
|
||||
// *san use a custom allocator that runs mmap/unmap under the hood. For
|
||||
// example:
|
||||
// https://github.com/llvm/llvm-project/blob/596d534ac3524052df210be8d3c01a33b2260a42/compiler-rt/lib/asan/asan_allocator.cpp#L980
|
||||
// https://github.com/llvm/llvm-project/blob/62ec4ac90738a5f2d209ed28c822223e58aaaeb7/compiler-rt/lib/sanitizer_common/sanitizer_allocator_secondary.h#L98
|
||||
AllowMmap();
|
||||
AllowSyscall(__NR_munmap);
|
||||
AllowSyscall(__NR_sched_yield);
|
||||
|
||||
// https://github.com/llvm/llvm-project/blob/4bbc3290a25c0dc26007912a96e0f77b2092ee56/compiler-rt/lib/sanitizer_common/sanitizer_stack_store.cpp#L293
|
||||
AddPolicyOnSyscall(__NR_mprotect,
|
||||
|
@ -367,7 +371,6 @@ PolicyBuilder& PolicyBuilder::AllowLlvmSanitizers() {
|
|||
OverridableBlockSyscallWithErrno(__NR_readlink, ENOENT);
|
||||
#endif
|
||||
OverridableBlockSyscallWithErrno(__NR_readlinkat, ENOENT);
|
||||
}
|
||||
if constexpr (sapi::sanitizers::IsASan()) {
|
||||
AllowSyscall(__NR_sigaltstack);
|
||||
}
|
||||
|
@ -377,6 +380,37 @@ PolicyBuilder& PolicyBuilder::AllowLlvmSanitizers() {
|
|||
return *this;
|
||||
}
|
||||
|
||||
PolicyBuilder& PolicyBuilder::AllowLlvmCoverage() {
|
||||
if (!sapi::IsCoverageRun()) {
|
||||
return *this;
|
||||
}
|
||||
AllowStat();
|
||||
AllowGetPIDs();
|
||||
AllowOpen();
|
||||
AllowRead();
|
||||
AllowWrite();
|
||||
AllowMkdir();
|
||||
AllowSafeFcntl();
|
||||
AllowSyscalls({
|
||||
__NR_munmap, __NR_close, __NR_lseek,
|
||||
#ifdef __NR__llseek
|
||||
__NR__llseek, // Newer glibc on PPC
|
||||
#endif
|
||||
});
|
||||
AllowTcMalloc();
|
||||
AddPolicyOnMmap([](bpf_labels& labels) -> std::vector<sock_filter> {
|
||||
return {
|
||||
ARG_32(2), // prot
|
||||
JNE32(PROT_READ | PROT_WRITE, JUMP(&labels, mmap_end)),
|
||||
ARG_32(3), // flags
|
||||
JEQ32(MAP_SHARED, ALLOW),
|
||||
LABEL(&labels, mmap_end),
|
||||
};
|
||||
});
|
||||
AddDirectoryIfNamespaced(getenv("COVERAGE_DIR"), /*is_ro=*/false);
|
||||
return *this;
|
||||
}
|
||||
|
||||
PolicyBuilder& PolicyBuilder::AllowLimitedMadvise() {
|
||||
return AddPolicyOnSyscall(__NR_madvise, {
|
||||
ARG_32(2),
|
||||
|
|
|
@ -239,6 +239,10 @@ class PolicyBuilder final {
|
|||
// all binaries.
|
||||
PolicyBuilder& AllowLlvmSanitizers();
|
||||
|
||||
// Allows system calls typically used by the LLVM coverage.
|
||||
// This method is intended as a best effort.
|
||||
PolicyBuilder& AllowLlvmCoverage();
|
||||
|
||||
// Appends code to allow mmap. Specifically this allows mmap and mmap2 syscall
|
||||
// on architectures where this syscalls exist.
|
||||
PolicyBuilder& AllowMmap();
|
||||
|
|
|
@ -20,14 +20,11 @@
|
|||
#include "absl/strings/string_view.h"
|
||||
#include "sandboxed_api/config.h"
|
||||
#include "sandboxed_api/sandbox2/allow_all_syscalls.h"
|
||||
#include "sandboxed_api/sandbox2/policybuilder.h"
|
||||
#include "sandboxed_api/util/path.h"
|
||||
|
||||
namespace sapi {
|
||||
|
||||
bool IsCoverageRun() {
|
||||
return getenv("COVERAGE") != nullptr;
|
||||
}
|
||||
|
||||
sandbox2::PolicyBuilder CreateDefaultPermissiveTestPolicy(
|
||||
absl::string_view bin_path) {
|
||||
sandbox2::PolicyBuilder builder;
|
||||
|
@ -35,6 +32,7 @@ sandbox2::PolicyBuilder CreateDefaultPermissiveTestPolicy(
|
|||
builder.DefaultAction(sandbox2::AllowAllSyscalls());
|
||||
if (sapi::host_os::IsAndroid()) {
|
||||
builder.DisableNamespaces();
|
||||
return builder;
|
||||
}
|
||||
if (IsCoverageRun()) {
|
||||
builder.AddDirectory(getenv("COVERAGE_DIR"), /*is_ro=*/false);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "sandboxed_api/config.h"
|
||||
#include "sandboxed_api/config.h" // IWYU pragma: export
|
||||
#include "sandboxed_api/sandbox2/policybuilder.h"
|
||||
|
||||
// The macro SKIP_ANDROID can be used in tests to skip running a
|
||||
|
@ -66,10 +66,14 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
namespace sapi {
|
||||
#define SKIP_SANITIZERS \
|
||||
do { \
|
||||
if (sapi::sanitizers::IsAny()) { \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Returns whether the executable running under code coverage.
|
||||
bool IsCoverageRun();
|
||||
namespace sapi {
|
||||
|
||||
sandbox2::PolicyBuilder CreateDefaultPermissiveTestPolicy(
|
||||
absl::string_view bin_path);
|
||||
|
|
Loading…
Reference in New Issue
Block a user