mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Decouple sandboxed stack tracing
This allows to split monitor & stack_trace related targets. Also move stack traces related functionality into MonitorBase. PiperOrigin-RevId: 510112916 Change-Id: I60eabf9c9b3204dc369713edd8ae05fded306875
This commit is contained in:
parent
d2dbbbae76
commit
71692bb50b
|
@ -308,11 +308,7 @@ cc_library(
|
|||
cc_library(
|
||||
name = "sandbox2",
|
||||
srcs = [
|
||||
"monitor_ptrace.cc",
|
||||
"monitor_ptrace.h",
|
||||
"sandbox2.cc",
|
||||
"stack_trace.cc",
|
||||
"stack_trace.h",
|
||||
],
|
||||
hdrs = [
|
||||
"client.h",
|
||||
|
@ -337,6 +333,7 @@ cc_library(
|
|||
":limits",
|
||||
":logsink",
|
||||
":monitor_base",
|
||||
":monitor_ptrace",
|
||||
":mounts",
|
||||
":namespace",
|
||||
":notify",
|
||||
|
@ -344,39 +341,88 @@ cc_library(
|
|||
":policybuilder",
|
||||
":regs",
|
||||
":result",
|
||||
":sanitizer",
|
||||
":stack_trace",
|
||||
":syscall",
|
||||
":util",
|
||||
":violation_cc_proto",
|
||||
"//sandboxed_api:config",
|
||||
"//sandboxed_api/sandbox2/network_proxy:client",
|
||||
"//sandboxed_api/sandbox2/network_proxy:filtering",
|
||||
"//sandboxed_api/util:fileops",
|
||||
"@com_google_absl//absl/base",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/container:flat_hash_set",
|
||||
"@com_google_absl//absl/log",
|
||||
"@com_google_absl//absl/log:check",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_absl//absl/types:optional",
|
||||
"@com_google_absl//absl/types:span",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "stack_trace",
|
||||
srcs = ["stack_trace.cc"],
|
||||
hdrs = ["stack_trace.h"],
|
||||
copts = sapi_platform_copts(),
|
||||
deps = [
|
||||
":comms",
|
||||
":executor",
|
||||
":limits",
|
||||
":namespace",
|
||||
":policy",
|
||||
":policybuilder",
|
||||
":regs",
|
||||
":result",
|
||||
"//sandboxed_api:config",
|
||||
"//sandboxed_api/sandbox2/unwind",
|
||||
"//sandboxed_api/sandbox2/unwind:unwind_cc_proto",
|
||||
"//sandboxed_api/sandbox2/util:bpf_helper",
|
||||
"//sandboxed_api/util:file_base",
|
||||
"//sandboxed_api/util:file_helpers",
|
||||
"//sandboxed_api/util:fileops",
|
||||
"//sandboxed_api/util:raw_logging",
|
||||
"//sandboxed_api/util:status",
|
||||
"//sandboxed_api/util:strerror",
|
||||
"//sandboxed_api/util:temp_file",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/cleanup",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/container:flat_hash_set",
|
||||
"@com_google_absl//absl/flags:flag",
|
||||
"@com_google_absl//absl/log",
|
||||
"@com_google_absl//absl/log:check",
|
||||
"@com_google_absl//absl/memory",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "monitor_ptrace",
|
||||
srcs = ["monitor_ptrace.cc"],
|
||||
hdrs = ["monitor_ptrace.h"],
|
||||
copts = sapi_platform_copts(),
|
||||
deps = [
|
||||
":client",
|
||||
":comms",
|
||||
":executor",
|
||||
":monitor_base",
|
||||
":notify",
|
||||
":policy",
|
||||
":regs",
|
||||
":result",
|
||||
":sanitizer",
|
||||
":syscall",
|
||||
":util",
|
||||
"//sandboxed_api:config",
|
||||
"//sandboxed_api/util:raw_logging",
|
||||
"//sandboxed_api/util:status",
|
||||
"@com_google_absl//absl/cleanup",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/container:flat_hash_set",
|
||||
"@com_google_absl//absl/flags:flag",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_absl//absl/types:optional",
|
||||
"@com_google_absl//absl/types:span",
|
||||
"@org_kernel_libcap//:libcap",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -396,7 +442,9 @@ cc_library(
|
|||
":namespace",
|
||||
":notify",
|
||||
":policy",
|
||||
":regs",
|
||||
":result",
|
||||
":stack_trace",
|
||||
":syscall",
|
||||
":util",
|
||||
"//sandboxed_api/sandbox2/network_proxy:server",
|
||||
|
@ -404,6 +452,7 @@ cc_library(
|
|||
"//sandboxed_api/util:raw_logging",
|
||||
"//sandboxed_api/util:strerror",
|
||||
"//sandboxed_api/util:temp_file",
|
||||
"@com_google_absl//absl/base",
|
||||
"@com_google_absl//absl/cleanup",
|
||||
"@com_google_absl//absl/flags:flag",
|
||||
"@com_google_absl//absl/log",
|
||||
|
@ -891,7 +940,6 @@ cc_test(
|
|||
cc_test(
|
||||
name = "stack_trace_test",
|
||||
srcs = [
|
||||
"stack_trace.h",
|
||||
"stack_trace_test.cc",
|
||||
],
|
||||
copts = sapi_platform_copts(),
|
||||
|
@ -902,6 +950,7 @@ cc_test(
|
|||
":namespace",
|
||||
":regs",
|
||||
":sandbox2",
|
||||
":stack_trace",
|
||||
"//sandboxed_api:testing",
|
||||
"//sandboxed_api/sandbox2/util:bpf_helper",
|
||||
"//sandboxed_api/util:fileops",
|
||||
|
|
|
@ -295,25 +295,19 @@ add_library(sandbox2_sandbox2 ${SAPI_LIB_TYPE}
|
|||
add_library(sandbox2::sandbox2 ALIAS sandbox2_sandbox2)
|
||||
target_link_libraries(sandbox2_sandbox2
|
||||
PRIVATE absl::core_headers
|
||||
absl::cleanup
|
||||
absl::flat_hash_set
|
||||
absl::memory
|
||||
absl::optional
|
||||
absl::str_format
|
||||
absl::strings
|
||||
sapi::strerror
|
||||
sapi::base
|
||||
PUBLIC absl::flat_hash_map
|
||||
absl::status
|
||||
absl::statusor
|
||||
absl::synchronization
|
||||
absl::time
|
||||
sapi::config
|
||||
sapi::file_base
|
||||
sapi::fileops
|
||||
sapi::status
|
||||
sapi::temp_file
|
||||
sandbox2::bpf_helper
|
||||
sandbox2::client
|
||||
sandbox2::comms
|
||||
sandbox2::executor
|
||||
|
@ -323,6 +317,7 @@ target_link_libraries(sandbox2_sandbox2
|
|||
sandbox2::limits
|
||||
sandbox2::logsink
|
||||
sandbox2::monitor_base
|
||||
sandbox2::monitor_ptrace
|
||||
sandbox2::mounts
|
||||
sandbox2::mount_tree_proto
|
||||
sandbox2::namespace
|
||||
|
@ -333,14 +328,47 @@ target_link_libraries(sandbox2_sandbox2
|
|||
sandbox2::policybuilder
|
||||
sandbox2::regs
|
||||
sandbox2::result
|
||||
sandbox2::sanitizer
|
||||
sandbox2::syscall
|
||||
sandbox2::unwind
|
||||
sandbox2::unwind_proto
|
||||
sandbox2::util
|
||||
sandbox2::violation_proto
|
||||
)
|
||||
|
||||
|
||||
# sandboxed_api/sandbox2:stack_trace
|
||||
add_library(sandbox2_stack_trace ${SAPI_LIB_TYPE}
|
||||
stack_trace.cc
|
||||
stack_trace.h
|
||||
)
|
||||
add_library(sandbox2::stack_trace ALIAS sandbox2_stack_trace)
|
||||
target_link_libraries(sandbox2_stack_trace
|
||||
PRIVATE absl::cleanup
|
||||
absl::flags
|
||||
absl::log
|
||||
absl::memory
|
||||
absl::status
|
||||
absl::strings
|
||||
sandbox2::client
|
||||
sandbox2::limits
|
||||
sandbox2::policybuilder
|
||||
sandbox2::util
|
||||
sandbox2::unwind
|
||||
sandbox2::unwind_proto
|
||||
sapi::base
|
||||
sapi::config
|
||||
sapi::file_base
|
||||
sapi::fileops
|
||||
sapi::raw_logging
|
||||
sapi::status
|
||||
PUBLIC absl::statusor
|
||||
sandbox2::comms
|
||||
sandbox2::executor
|
||||
sandbox2::namespace
|
||||
sandbox2::policy
|
||||
sandbox2::result
|
||||
sandbox2::regs
|
||||
)
|
||||
|
||||
|
||||
# sandboxed_api/sandbox2:monitor_base
|
||||
add_library(sandbox2_monitor_base ${SAPI_LIB_TYPE}
|
||||
monitor_base.cc
|
||||
|
@ -355,6 +383,7 @@ target_link_libraries(sandbox2_monitor_base
|
|||
sandbox2::limits
|
||||
sandbox2::mounts
|
||||
sandbox2::namespace
|
||||
sandbox2::stack_trace
|
||||
sandbox2::util
|
||||
sapi::file_helpers
|
||||
sapi::temp_file
|
||||
|
@ -373,6 +402,38 @@ target_link_libraries(sandbox2_monitor_base
|
|||
sandbox2::syscall
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2:monitor_ptrace
|
||||
add_library(sandbox2_monitor_ptrace ${SAPI_LIB_TYPE}
|
||||
monitor_ptrace.cc
|
||||
monitor_ptrace.h
|
||||
)
|
||||
add_library(sandbox2::monitor_ptrace ALIAS sandbox2_monitor_ptrace)
|
||||
target_link_libraries(sandbox2_monitor_ptrace
|
||||
PRIVATE absl::cleanup
|
||||
absl::flat_hash_set
|
||||
absl::flags
|
||||
absl::status
|
||||
absl::strings
|
||||
absl::time
|
||||
sapi::base
|
||||
sapi::config
|
||||
sapi::status
|
||||
sandbox2::client
|
||||
sandbox2::comms
|
||||
sandbox2::result
|
||||
sandbox2::sanitizer
|
||||
sandbox2::util
|
||||
PUBLIC sandbox2::executor
|
||||
sandbox2::monitor_base
|
||||
sandbox2::notify
|
||||
sandbox2::policy
|
||||
sandbox2::regs
|
||||
sandbox2::syscall
|
||||
absl::synchronization
|
||||
absl::flat_hash_map
|
||||
sapi::raw_logging
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2:policybuilder
|
||||
add_library(sandbox2_policybuilder ${SAPI_LIB_TYPE}
|
||||
policybuilder.cc
|
||||
|
@ -1001,6 +1062,7 @@ if(BUILD_TESTING AND SAPI_BUILD_TESTING)
|
|||
sandbox2::global_forkserver
|
||||
sandbox2::namespace
|
||||
sandbox2::sandbox2
|
||||
sandbox2::stack_trace
|
||||
sandbox2::util
|
||||
sapi::fileops
|
||||
sapi::temp_file
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "sandboxed_api/sandbox2/network_proxy/server.h"
|
||||
#include "sandboxed_api/sandbox2/policy.h"
|
||||
#include "sandboxed_api/sandbox2/result.h"
|
||||
#include "sandboxed_api/sandbox2/stack_trace.h"
|
||||
#include "sandboxed_api/sandbox2/syscall.h"
|
||||
#include "sandboxed_api/sandbox2/util.h"
|
||||
#include "sandboxed_api/util/file_helpers.h"
|
||||
|
@ -60,6 +61,8 @@ ABSL_FLAG(bool, sandbox2_report_on_sandboxee_timeout, true,
|
|||
ABSL_DECLARE_FLAG(bool, sandbox2_danger_danger_permit_all);
|
||||
ABSL_DECLARE_FLAG(std::string, sandbox2_danger_danger_permit_all_and_log);
|
||||
|
||||
ABSL_DECLARE_FLAG(bool, sandbox_libunwind_crash_handler);
|
||||
|
||||
namespace sandbox2 {
|
||||
namespace {
|
||||
|
||||
|
@ -118,7 +121,8 @@ MonitorBase::MonitorBase(Executor* executor, Policy* policy, Notify* notify)
|
|||
policy_(policy),
|
||||
// NOLINTNEXTLINE clang-diagnostic-deprecated-declarations
|
||||
comms_(executor_->ipc()->comms()),
|
||||
ipc_(executor_->ipc()) {
|
||||
ipc_(executor_->ipc()),
|
||||
uses_custom_forkserver_(executor_->fork_client_ != nullptr) {
|
||||
// It's a pre-connected Comms channel, no need to accept new connection.
|
||||
CHECK(comms_->IsConnected());
|
||||
std::string path =
|
||||
|
@ -383,6 +387,20 @@ void MonitorBase::LogSyscallViolationExplanation(const Syscall& syscall) const {
|
|||
}
|
||||
}
|
||||
|
||||
bool MonitorBase::StackTraceCollectionPossible() const {
|
||||
// Only get the stacktrace if we are not in the libunwind sandbox (avoid
|
||||
// recursion).
|
||||
if ((policy_->GetNamespace() ||
|
||||
absl::GetFlag(FLAGS_sandbox_libunwind_crash_handler) == false) &&
|
||||
executor_->libunwind_sbox_for_pid_ == 0) {
|
||||
return true;
|
||||
}
|
||||
LOG(ERROR) << "Cannot collect stack trace. Unwind pid "
|
||||
<< executor_->libunwind_sbox_for_pid_ << ", namespace "
|
||||
<< policy_->GetNamespace();
|
||||
return false;
|
||||
}
|
||||
|
||||
void MonitorBase::EnableNetworkProxyServer() {
|
||||
int fd = ipc_->ReceiveFd(NetworkProxyClient::kFDName);
|
||||
|
||||
|
@ -392,4 +410,46 @@ void MonitorBase::EnableNetworkProxyServer() {
|
|||
network_proxy_thread_ = std::thread(&NetworkProxyServer::Run,
|
||||
network_proxy_server_.get());
|
||||
}
|
||||
|
||||
bool MonitorBase::ShouldCollectStackTrace(Result::StatusEnum status) const {
|
||||
if (!StackTraceCollectionPossible()) {
|
||||
return false;
|
||||
}
|
||||
switch (status) {
|
||||
case Result::EXTERNAL_KILL:
|
||||
return policy_->collect_stacktrace_on_kill_;
|
||||
case Result::TIMEOUT:
|
||||
return policy_->collect_stacktrace_on_timeout_;
|
||||
case Result::SIGNALED:
|
||||
return policy_->collect_stacktrace_on_signal_;
|
||||
case Result::VIOLATION:
|
||||
return policy_->collect_stacktrace_on_violation_;
|
||||
case Result::OK:
|
||||
return policy_->collect_stacktrace_on_exit_;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
absl::StatusOr<std::vector<std::string>> MonitorBase::GetStackTrace(
|
||||
const Regs* regs) {
|
||||
return sandbox2::GetStackTrace(regs, policy_->GetNamespace(),
|
||||
uses_custom_forkserver_);
|
||||
}
|
||||
|
||||
absl::StatusOr<std::vector<std::string>> MonitorBase::GetAndLogStackTrace(
|
||||
const Regs* regs) {
|
||||
auto stack_trace = GetStackTrace(regs);
|
||||
if (!stack_trace.ok()) {
|
||||
return stack_trace.status();
|
||||
}
|
||||
|
||||
LOG(INFO) << "Stack trace: [";
|
||||
for (const auto& frame : CompactStackTrace(*stack_trace)) {
|
||||
LOG(INFO) << " " << frame;
|
||||
}
|
||||
LOG(INFO) << "]";
|
||||
|
||||
return stack_trace;
|
||||
}
|
||||
} // namespace sandbox2
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/statusor.h"
|
||||
#include "absl/synchronization/notification.h"
|
||||
|
@ -34,6 +36,7 @@
|
|||
#include "sandboxed_api/sandbox2/network_proxy/server.h"
|
||||
#include "sandboxed_api/sandbox2/notify.h"
|
||||
#include "sandboxed_api/sandbox2/policy.h"
|
||||
#include "sandboxed_api/sandbox2/regs.h"
|
||||
#include "sandboxed_api/sandbox2/result.h"
|
||||
#include "sandboxed_api/sandbox2/syscall.h"
|
||||
|
||||
|
@ -78,6 +81,19 @@ class MonitorBase {
|
|||
// explanation for the reason of the violation.
|
||||
void LogSyscallViolation(const Syscall& syscall) const;
|
||||
|
||||
// Tells if collecting stack trace is at all possible.
|
||||
bool StackTraceCollectionPossible() const;
|
||||
|
||||
// Whether a stack trace should be collected given the current status
|
||||
bool ShouldCollectStackTrace(Result::StatusEnum status) const;
|
||||
|
||||
// Gets stack trace.
|
||||
absl::StatusOr<std::vector<std::string>> GetStackTrace(const Regs* regs);
|
||||
|
||||
// Gets and logs stack trace.
|
||||
absl::StatusOr<std::vector<std::string>> GetAndLogStackTrace(
|
||||
const Regs* regs);
|
||||
|
||||
// Internal objects, owned by the Sandbox2 object.
|
||||
Executor* executor_;
|
||||
Notify* notify_;
|
||||
|
@ -134,6 +150,9 @@ class MonitorBase {
|
|||
std::string comms_fd_dev_;
|
||||
|
||||
std::thread network_proxy_thread_;
|
||||
|
||||
// Is the sandboxee forked from a custom forkserver?
|
||||
bool uses_custom_forkserver_;
|
||||
};
|
||||
|
||||
} // namespace sandbox2
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include "sandboxed_api/sandbox2/regs.h"
|
||||
#include "sandboxed_api/sandbox2/result.h"
|
||||
#include "sandboxed_api/sandbox2/sanitizer.h"
|
||||
#include "sandboxed_api/sandbox2/stack_trace.h"
|
||||
#include "sandboxed_api/sandbox2/syscall.h"
|
||||
#include "sandboxed_api/sandbox2/util.h"
|
||||
#include "sandboxed_api/util/raw_logging.h"
|
||||
|
@ -63,7 +62,6 @@ ABSL_FLAG(absl::Duration, sandbox2_stack_traces_collection_timeout,
|
|||
"traces is enabled.");
|
||||
|
||||
ABSL_DECLARE_FLAG(bool, sandbox2_danger_danger_permit_all);
|
||||
ABSL_DECLARE_FLAG(bool, sandbox_libunwind_crash_handler);
|
||||
|
||||
namespace sandbox2 {
|
||||
namespace {
|
||||
|
@ -178,8 +176,7 @@ void CompleteSyscall(pid_t pid, int signo) {
|
|||
|
||||
PtraceMonitor::PtraceMonitor(Executor* executor, Policy* policy, Notify* notify)
|
||||
: MonitorBase(executor, policy, notify),
|
||||
wait_for_execve_(executor->enable_sandboxing_pre_execve_),
|
||||
uses_custom_forkserver_(executor_->fork_client_ != nullptr) {
|
||||
wait_for_execve_(executor->enable_sandboxing_pre_execve_) {
|
||||
if (executor_->limits()->wall_time_limit() != absl::ZeroDuration()) {
|
||||
auto deadline = absl::Now() + executor_->limits()->wall_time_limit();
|
||||
deadline_millis_.store(absl::ToUnixMillis(deadline),
|
||||
|
@ -196,62 +193,12 @@ bool PtraceMonitor::IsActivelyMonitoring() {
|
|||
|
||||
void PtraceMonitor::SetActivelyMonitoring() { wait_for_execve_ = false; }
|
||||
|
||||
bool PtraceMonitor::StackTraceCollectionPossible() const {
|
||||
// Only get the stacktrace if we are not in the libunwind sandbox (avoid
|
||||
// recursion).
|
||||
if ((policy_->GetNamespace() ||
|
||||
absl::GetFlag(FLAGS_sandbox_libunwind_crash_handler) == false) &&
|
||||
executor_->libunwind_sbox_for_pid_ == 0) {
|
||||
return true;
|
||||
} else {
|
||||
LOG(ERROR) << "Cannot collect stack trace. Unwind pid "
|
||||
<< executor_->libunwind_sbox_for_pid_ << ", namespace "
|
||||
<< policy_->GetNamespace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool PtraceMonitor::ShouldCollectStackTrace() const {
|
||||
if (!StackTraceCollectionPossible()) {
|
||||
return false;
|
||||
}
|
||||
switch (result_.final_status()) {
|
||||
case Result::EXTERNAL_KILL:
|
||||
return policy_->collect_stacktrace_on_kill_;
|
||||
case Result::TIMEOUT:
|
||||
return policy_->collect_stacktrace_on_timeout_;
|
||||
case Result::SIGNALED:
|
||||
return policy_->collect_stacktrace_on_signal_;
|
||||
case Result::VIOLATION:
|
||||
return policy_->collect_stacktrace_on_violation_;
|
||||
case Result::OK:
|
||||
return policy_->collect_stacktrace_on_exit_;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
absl::StatusOr<std::vector<std::string>> PtraceMonitor::GetAndLogStackTrace(
|
||||
const Regs* regs) {
|
||||
SAPI_ASSIGN_OR_RETURN(
|
||||
std::vector<std::string> stack_trace,
|
||||
GetStackTrace(regs, policy_->GetNamespace(), uses_custom_forkserver_));
|
||||
|
||||
LOG(INFO) << "Stack trace: [";
|
||||
for (const auto& frame : CompactStackTrace(stack_trace)) {
|
||||
LOG(INFO) << " " << frame;
|
||||
}
|
||||
LOG(INFO) << "]";
|
||||
|
||||
return stack_trace;
|
||||
}
|
||||
|
||||
void PtraceMonitor::SetAdditionalResultInfo(std::unique_ptr<Regs> regs) {
|
||||
pid_t pid = regs->pid();
|
||||
result_.SetRegs(std::move(regs));
|
||||
result_.SetProgName(util::GetProgName(pid));
|
||||
result_.SetProcMaps(ReadProcMaps(pid));
|
||||
if (!ShouldCollectStackTrace()) {
|
||||
if (!ShouldCollectStackTrace(result_.final_status())) {
|
||||
VLOG(1) << "Stack traces have been disabled";
|
||||
return;
|
||||
}
|
||||
|
@ -970,8 +917,7 @@ void PtraceMonitor::StateProcessStopped(pid_t pid, int status) {
|
|||
pid]() -> absl::StatusOr<std::vector<std::string>> {
|
||||
Regs regs(pid);
|
||||
SAPI_RETURN_IF_ERROR(regs.Fetch());
|
||||
return GetStackTrace(®s, policy_->GetNamespace(),
|
||||
uses_custom_forkserver_);
|
||||
return GetStackTrace(®s);
|
||||
}();
|
||||
|
||||
if (!stack_trace.ok()) {
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <thread>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/status/statusor.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/synchronization/notification.h"
|
||||
#include "sandboxed_api/sandbox2/executor.h"
|
||||
|
@ -33,7 +32,6 @@
|
|||
#include "sandboxed_api/sandbox2/notify.h"
|
||||
#include "sandboxed_api/sandbox2/policy.h"
|
||||
#include "sandboxed_api/sandbox2/regs.h"
|
||||
#include "sandboxed_api/sandbox2/result.h"
|
||||
#include "sandboxed_api/sandbox2/syscall.h"
|
||||
#include "sandboxed_api/util/raw_logging.h"
|
||||
|
||||
|
@ -89,12 +87,6 @@ class PtraceMonitor : public MonitorBase {
|
|||
// Process with given PID changed state to a stopped state.
|
||||
void StateProcessStopped(pid_t pid, int status);
|
||||
|
||||
// Tells if collecting stack trace is at all possible.
|
||||
bool StackTraceCollectionPossible() const;
|
||||
|
||||
// Whether a stack trace should be collected given the current status
|
||||
bool ShouldCollectStackTrace() const;
|
||||
|
||||
// Sets additional information in the result object, such as program name,
|
||||
// stack trace etc.
|
||||
void SetAdditionalResultInfo(std::unique_ptr<Regs> regs);
|
||||
|
@ -103,10 +95,6 @@ class PtraceMonitor : public MonitorBase {
|
|||
void ActionProcessSyscallViolation(Regs* regs, const Syscall& syscall,
|
||||
ViolationType violation_type);
|
||||
|
||||
// Gets and logs stack trace.
|
||||
absl::StatusOr<std::vector<std::string>> GetAndLogStackTrace(
|
||||
const Regs* regs);
|
||||
|
||||
void LogStackTraceOfPid(pid_t pid);
|
||||
|
||||
// Ptrace events:
|
||||
|
@ -166,8 +154,6 @@ class PtraceMonitor : public MonitorBase {
|
|||
// Syscalls that are running, whose result values we want to inspect.
|
||||
absl::flat_hash_map<pid_t, Syscall> syscalls_in_progress_;
|
||||
sigset_t sset_;
|
||||
// Is the sandboxee forked from a custom forkserver?
|
||||
bool uses_custom_forkserver_;
|
||||
|
||||
// Monitor thread object.
|
||||
std::unique_ptr<std::thread> thread_;
|
||||
|
|
|
@ -19,15 +19,45 @@
|
|||
#include <csignal>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/call_once.h"
|
||||
#include "absl/log/check.h"
|
||||
#include "absl/status/statusor.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "sandboxed_api/sandbox2/monitor_base.h"
|
||||
#include "sandboxed_api/sandbox2/monitor_ptrace.h"
|
||||
#include "sandboxed_api/sandbox2/result.h"
|
||||
#include "sandboxed_api/sandbox2/stack_trace.h"
|
||||
|
||||
namespace sandbox2 {
|
||||
|
||||
namespace {
|
||||
|
||||
class Sandbox2Peer : public internal::SandboxPeer {
|
||||
public:
|
||||
static std::unique_ptr<SandboxPeer> Spawn(std::unique_ptr<Executor> executor,
|
||||
std::unique_ptr<Policy> policy) {
|
||||
return std::make_unique<Sandbox2Peer>(std::move(executor),
|
||||
std::move(policy));
|
||||
}
|
||||
|
||||
Sandbox2Peer(std::unique_ptr<Executor> executor,
|
||||
std::unique_ptr<Policy> policy)
|
||||
: sandbox_(std::move(executor), std::move(policy)) {
|
||||
sandbox_.RunAsync();
|
||||
}
|
||||
|
||||
Comms* comms() override { return sandbox_.comms(); }
|
||||
void Kill() override { sandbox_.Kill(); }
|
||||
Result AwaitResult() override { return sandbox_.AwaitResult(); }
|
||||
|
||||
private:
|
||||
Sandbox2 sandbox_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
absl::StatusOr<Result> Sandbox2::AwaitResultWithTimeout(
|
||||
absl::Duration timeout) {
|
||||
CHECK(monitor_ != nullptr) << "Sandbox was not launched yet";
|
||||
|
@ -70,6 +100,11 @@ void Sandbox2::set_walltime_limit(absl::Duration limit) const {
|
|||
}
|
||||
|
||||
void Sandbox2::Launch() {
|
||||
static absl::once_flag init_sandbox_peer_flag;
|
||||
absl::call_once(init_sandbox_peer_flag, []() {
|
||||
internal::SandboxPeer::spawn_fn_ = Sandbox2Peer::Spawn;
|
||||
});
|
||||
|
||||
monitor_ = std::make_unique<PtraceMonitor>(executor_.get(), policy_.get(),
|
||||
notify_.get());
|
||||
monitor_->Launch();
|
||||
|
|
|
@ -29,23 +29,18 @@
|
|||
#include "absl/log/log.h"
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/strings/numbers.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/strip.h"
|
||||
#include "libcap/include/sys/capability.h"
|
||||
#include "sandboxed_api/config.h"
|
||||
#include "sandboxed_api/sandbox2/comms.h"
|
||||
#include "sandboxed_api/sandbox2/executor.h"
|
||||
#include "sandboxed_api/sandbox2/ipc.h"
|
||||
#include "sandboxed_api/sandbox2/limits.h"
|
||||
#include "sandboxed_api/sandbox2/policy.h"
|
||||
#include "sandboxed_api/sandbox2/policybuilder.h"
|
||||
#include "sandboxed_api/sandbox2/regs.h"
|
||||
#include "sandboxed_api/sandbox2/result.h"
|
||||
#include "sandboxed_api/sandbox2/sandbox2.h"
|
||||
#include "sandboxed_api/sandbox2/unwind/unwind.h"
|
||||
#include "sandboxed_api/sandbox2/unwind/unwind.pb.h"
|
||||
#include "sandboxed_api/sandbox2/util/bpf_helper.h"
|
||||
#include "sandboxed_api/util/fileops.h"
|
||||
#include "sandboxed_api/util/path.h"
|
||||
#include "sandboxed_api/util/raw_logging.h"
|
||||
|
@ -79,7 +74,7 @@ class StackTracePeer {
|
|||
const std::string& app_path, const std::string& exe_path,
|
||||
const Namespace* ns, bool uses_custom_forkserver);
|
||||
|
||||
static absl::StatusOr<UnwindResult> LaunchLibunwindSandbox(
|
||||
static absl::StatusOr<std::vector<std::string>> LaunchLibunwindSandbox(
|
||||
const Regs* regs, const Namespace* ns, bool uses_custom_forkserver);
|
||||
};
|
||||
|
||||
|
@ -163,7 +158,11 @@ absl::StatusOr<std::unique_ptr<Policy>> StackTracePeer::GetPolicy(
|
|||
return std::move(policy);
|
||||
}
|
||||
|
||||
absl::StatusOr<UnwindResult> StackTracePeer::LaunchLibunwindSandbox(
|
||||
namespace internal {
|
||||
SandboxPeer::SpawnFn SandboxPeer::spawn_fn_ = nullptr;
|
||||
} // namespace internal
|
||||
|
||||
absl::StatusOr<std::vector<std::string>> StackTracePeer::LaunchLibunwindSandbox(
|
||||
const Regs* regs, const Namespace* ns, bool uses_custom_forkserver) {
|
||||
const pid_t pid = regs->pid();
|
||||
|
||||
|
@ -240,11 +239,11 @@ absl::StatusOr<UnwindResult> StackTracePeer::LaunchLibunwindSandbox(
|
|||
std::unique_ptr<Policy> policy,
|
||||
StackTracePeer::GetPolicy(pid, unwind_temp_maps_path, app_path, exe_path,
|
||||
ns, uses_custom_forkserver));
|
||||
Sandbox2 sandbox(std::move(executor), std::move(policy));
|
||||
|
||||
VLOG(1) << "Running libunwind sandbox";
|
||||
sandbox.RunAsync();
|
||||
Comms* comms = sandbox.comms();
|
||||
auto sandbox =
|
||||
internal::SandboxPeer::Spawn(std::move(executor), std::move(policy));
|
||||
Comms* comms = sandbox->comms();
|
||||
|
||||
UnwindSetup msg;
|
||||
msg.set_pid(pid);
|
||||
|
@ -253,8 +252,8 @@ absl::StatusOr<UnwindResult> StackTracePeer::LaunchLibunwindSandbox(
|
|||
msg.set_default_max_frames(kDefaultMaxFrames);
|
||||
|
||||
absl::Cleanup kill_sandbox = [&sandbox]() {
|
||||
sandbox.Kill();
|
||||
sandbox.AwaitResult().IgnoreResult();
|
||||
sandbox->Kill();
|
||||
sandbox->AwaitResult().IgnoreResult();
|
||||
};
|
||||
|
||||
if (!comms->SendProtoBuf(msg)) {
|
||||
|
@ -277,7 +276,7 @@ absl::StatusOr<UnwindResult> StackTracePeer::LaunchLibunwindSandbox(
|
|||
|
||||
std::move(kill_sandbox).Cancel();
|
||||
|
||||
auto sandbox_result = sandbox.AwaitResult();
|
||||
auto sandbox_result = sandbox->AwaitResult();
|
||||
|
||||
LOG(INFO) << "Libunwind execution status: " << sandbox_result.ToString();
|
||||
|
||||
|
@ -287,7 +286,8 @@ absl::StatusOr<UnwindResult> StackTracePeer::LaunchLibunwindSandbox(
|
|||
sandbox_result.ToString()));
|
||||
}
|
||||
|
||||
return result;
|
||||
return std::vector<std::string>(result.stacktrace().begin(),
|
||||
result.stacktrace().end());
|
||||
}
|
||||
|
||||
absl::StatusOr<std::vector<std::string>> GetStackTrace(
|
||||
|
@ -317,11 +317,8 @@ absl::StatusOr<std::vector<std::string>> GetStackTrace(
|
|||
return UnsafeGetStackTrace(regs->pid());
|
||||
}
|
||||
|
||||
SAPI_ASSIGN_OR_RETURN(
|
||||
UnwindResult res,
|
||||
StackTracePeer::LaunchLibunwindSandbox(regs, ns, uses_custom_forkserver));
|
||||
return std::vector<std::string>(res.stacktrace().begin(),
|
||||
res.stacktrace().end());
|
||||
return StackTracePeer::LaunchLibunwindSandbox(regs, ns,
|
||||
uses_custom_forkserver);
|
||||
}
|
||||
|
||||
std::vector<std::string> CompactStackTrace(
|
||||
|
|
|
@ -19,15 +19,47 @@
|
|||
#ifndef SANDBOXED_API_SANDBOX2_STACK_TRACE_H_
|
||||
#define SANDBOXED_API_SANDBOX2_STACK_TRACE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/statusor.h"
|
||||
#include "sandboxed_api/sandbox2/comms.h"
|
||||
#include "sandboxed_api/sandbox2/executor.h"
|
||||
#include "sandboxed_api/sandbox2/namespace.h"
|
||||
#include "sandboxed_api/sandbox2/policy.h"
|
||||
#include "sandboxed_api/sandbox2/regs.h"
|
||||
#include "sandboxed_api/sandbox2/result.h"
|
||||
|
||||
namespace sandbox2 {
|
||||
|
||||
class Sandbox2;
|
||||
|
||||
namespace internal {
|
||||
|
||||
class SandboxPeer {
|
||||
public:
|
||||
static std::unique_ptr<SandboxPeer> Spawn(std::unique_ptr<Executor> executor,
|
||||
std::unique_ptr<Policy> policy) {
|
||||
CHECK_NE(spawn_fn_, nullptr);
|
||||
return spawn_fn_(std::move(executor), std::move(policy));
|
||||
}
|
||||
|
||||
virtual ~SandboxPeer() = default;
|
||||
|
||||
virtual Comms* comms() = 0;
|
||||
virtual void Kill() = 0;
|
||||
virtual Result AwaitResult() = 0;
|
||||
|
||||
private:
|
||||
friend class ::sandbox2::Sandbox2;
|
||||
using SpawnFn = std::unique_ptr<SandboxPeer> (*)(std::unique_ptr<Executor>,
|
||||
std::unique_ptr<Policy>);
|
||||
static SpawnFn spawn_fn_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Maximum depth of analyzed call stack.
|
||||
constexpr size_t kDefaultMaxFrames = 200;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user