mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Now network proxy server supports IP filtering. API to policybuilder is added to make a list of allowed pairs of allowed IP, mask and port where mask and port are optional.
PiperOrigin-RevId: 294640297 Change-Id: I4c6520685a658f8b7762af238588830f71b3f54a
This commit is contained in:
parent
f1ce6fcb87
commit
800339d672
|
@ -89,7 +89,7 @@ cc_library(
|
|||
":syscall",
|
||||
":util",
|
||||
"//sandboxed_api/util:status",
|
||||
"@com_google_absl//absl/base",
|
||||
"//sandboxed_api/util:statusor",
|
||||
"@com_google_absl//absl/memory",
|
||||
"@com_google_absl//absl/strings",
|
||||
],
|
||||
|
@ -127,36 +127,6 @@ cc_library(
|
|||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "network_proxy_server",
|
||||
srcs = ["network_proxy_server.cc"],
|
||||
hdrs = ["network_proxy_server.h"],
|
||||
copts = sapi_platform_copts(),
|
||||
deps = [
|
||||
":comms",
|
||||
"//sandboxed_api/sandbox2/util:fileops",
|
||||
"@com_google_absl//absl/memory",
|
||||
"@com_google_glog//:glog",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "network_proxy_client",
|
||||
srcs = ["network_proxy_client.cc"],
|
||||
hdrs = ["network_proxy_client.h"],
|
||||
copts = sapi_platform_copts(),
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":comms",
|
||||
"//sandboxed_api/sandbox2/util:strerror",
|
||||
"//sandboxed_api/util:status",
|
||||
"@com_google_absl//absl/memory",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_glog//:glog",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "ipc",
|
||||
srcs = ["ipc.cc"],
|
||||
|
@ -166,8 +136,6 @@ cc_library(
|
|||
":comms",
|
||||
":logserver",
|
||||
":logsink",
|
||||
":network_proxy_client",
|
||||
":network_proxy_server",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/memory",
|
||||
"@com_google_absl//absl/strings",
|
||||
|
@ -186,6 +154,7 @@ cc_library(
|
|||
":regs",
|
||||
":syscall",
|
||||
":violation_cc_proto",
|
||||
"//sandboxed_api/sandbox2/network_proxy:filtering",
|
||||
"//sandboxed_api/sandbox2/util:bpf_helper",
|
||||
"//sandboxed_api/util:flags",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
|
@ -306,10 +275,10 @@ cc_library(
|
|||
":client",
|
||||
":executor",
|
||||
":comms",
|
||||
":violation_cc_proto",
|
||||
":forkserver",
|
||||
":forkserver_cc_proto",
|
||||
":global_forkserver",
|
||||
":violation_cc_proto",
|
||||
":forkserver",
|
||||
":ipc",
|
||||
":limits",
|
||||
":logsink",
|
||||
|
@ -321,7 +290,6 @@ cc_library(
|
|||
":result",
|
||||
":syscall",
|
||||
":util",
|
||||
":network_proxy_client",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/container:flat_hash_set",
|
||||
|
@ -333,12 +301,17 @@ cc_library(
|
|||
"@com_google_absl//absl/time",
|
||||
"@com_google_absl//absl/types:optional",
|
||||
"@org_kernel_libcap//:libcap",
|
||||
"//sandboxed_api/sandbox2/network_proxy:client",
|
||||
"//sandboxed_api/sandbox2/network_proxy:filtering",
|
||||
"//sandboxed_api/sandbox2/network_proxy:server",
|
||||
"//sandboxed_api/sandbox2/unwind",
|
||||
"//sandboxed_api/sandbox2/unwind:unwind_cc_proto",
|
||||
"//sandboxed_api/sandbox2/util:bpf_helper",
|
||||
"//sandboxed_api/sandbox2/util:file_base",
|
||||
"//sandboxed_api/sandbox2/util:fileops",
|
||||
"//sandboxed_api/sandbox2/util:strerror",
|
||||
"//sandboxed_api/util:raw_logging",
|
||||
"//util/functional",
|
||||
"//sandboxed_api/util:status",
|
||||
"//sandboxed_api/util:statusor",
|
||||
|
||||
|
@ -364,7 +337,7 @@ cc_library(
|
|||
deps = [
|
||||
":comms",
|
||||
":logsink",
|
||||
":network_proxy_client",
|
||||
"//sandboxed_api/sandbox2/network_proxy:client",
|
||||
"//sandboxed_api/sandbox2/util:file_helpers",
|
||||
"//sandboxed_api/sandbox2/util:fileops",
|
||||
"//sandboxed_api/sandbox2/util:strerror",
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
add_subdirectory(examples)
|
||||
add_subdirectory(unwind)
|
||||
add_subdirectory(util)
|
||||
add_subdirectory(network_proxy)
|
||||
|
||||
# sandboxed_api/sandbox2:bpfdisassembler
|
||||
add_library(sandbox2_bpfdisassembler STATIC
|
||||
|
@ -121,36 +122,6 @@ target_link_libraries(sandbox2_logsink
|
|||
PUBLIC glog::glog
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2:network_proxy_server
|
||||
add_library(sandbox2_network_proxy_server STATIC
|
||||
network_proxy_server.cc
|
||||
network_proxy_server.h
|
||||
)
|
||||
add_library(sandbox2::network_proxy_server ALIAS sandbox2_network_proxy_server)
|
||||
target_link_libraries(sandbox2_network_proxy_server PRIVATE
|
||||
absl::memory
|
||||
glog::glog
|
||||
sandbox2::comms
|
||||
sandbox2::fileops
|
||||
sapi::base
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2:network_proxy_client
|
||||
add_library(sandbox2_network_proxy_client STATIC
|
||||
network_proxy_client.cc
|
||||
network_proxy_client.h
|
||||
)
|
||||
add_library(sandbox2::network_proxy_client ALIAS sandbox2_network_proxy_client)
|
||||
target_link_libraries(sandbox2_network_proxy_client PRIVATE
|
||||
absl::strings
|
||||
absl::synchronization
|
||||
glog::glog
|
||||
sandbox2::comms
|
||||
sandbox2::strerror
|
||||
sapi::base
|
||||
sapi::status
|
||||
)
|
||||
|
||||
# sandboxed_api/sandbox2:ipc
|
||||
add_library(sandbox2_ipc STATIC
|
||||
ipc.cc
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include "absl/strings/str_join.h"
|
||||
#include "absl/strings/str_split.h"
|
||||
#include "sandboxed_api/sandbox2/comms.h"
|
||||
#include "sandboxed_api/sandbox2/network_proxy_client.h"
|
||||
#include "sandboxed_api/sandbox2/sanitizer.h"
|
||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||
#include "sandboxed_api/util/raw_logging.h"
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include "sandboxed_api/sandbox2/comms.h"
|
||||
#include "sandboxed_api/sandbox2/logsink.h"
|
||||
#include "sandboxed_api/sandbox2/network_proxy_client.h"
|
||||
#include "sandboxed_api/sandbox2/network_proxy/client.h"
|
||||
|
||||
namespace sandbox2 {
|
||||
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
|
||||
# The 'network proxy' example demonstrates how to use network proxy server.
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load("//sandboxed_api/bazel:build_defs.bzl", "sapi_platform_copts")
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
# Executor
|
||||
cc_binary(
|
||||
name = "networkproxy_sandbox",
|
||||
|
@ -27,6 +27,7 @@ cc_binary(
|
|||
deps = [
|
||||
"//sandboxed_api/sandbox2",
|
||||
"//sandboxed_api/sandbox2:comms",
|
||||
"//sandboxed_api/sandbox2/network_proxy:filtering",
|
||||
"//sandboxed_api/sandbox2/util:bpf_helper",
|
||||
"//sandboxed_api/sandbox2/util:fileops",
|
||||
"//sandboxed_api/sandbox2/util:runfiles",
|
||||
|
@ -42,7 +43,7 @@ cc_binary(
|
|||
deps = [
|
||||
"//sandboxed_api/sandbox2:client",
|
||||
"//sandboxed_api/sandbox2:comms",
|
||||
"//sandboxed_api/sandbox2:network_proxy_client",
|
||||
"//sandboxed_api/sandbox2/network_proxy:client",
|
||||
"//sandboxed_api/sandbox2/util:fileops",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
],
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "absl/strings/str_format.h"
|
||||
#include "sandboxed_api/sandbox2/client.h"
|
||||
#include "sandboxed_api/sandbox2/comms.h"
|
||||
#include "sandboxed_api/sandbox2/network_proxy_client.h"
|
||||
#include "sandboxed_api/sandbox2/network_proxy/client.h"
|
||||
#include "sandboxed_api/sandbox2/util/fileops.h"
|
||||
|
||||
static ssize_t ReadFromFd(int fd, uint8_t* buf, size_t size) {
|
||||
|
@ -113,5 +113,6 @@ int main(int argc, char** argv) {
|
|||
if (!CommunicationTest(client.get())) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ std::unique_ptr<sandbox2::Policy> GetPolicy(absl::string_view sandboxee_path) {
|
|||
.AllowSyscall(__NR_munmap)
|
||||
.AllowSyscall(__NR_getpid)
|
||||
.AddNetworkProxyHandlerPolicy()
|
||||
.AllowTcMalloc()
|
||||
.AllowIPv6("::1")
|
||||
.AddLibrariesForBinary(sandboxee_path)
|
||||
.BuildOrDie();
|
||||
}
|
||||
|
@ -129,10 +131,7 @@ int main(int argc, char** argv) {
|
|||
// is capable of enabling sandboxing on its own).
|
||||
->set_enable_sandbox_before_exec(false)
|
||||
// Set cwd to / to get rids of warnings connected with file namespace.
|
||||
.set_cwd("/")
|
||||
// Enable built-in network proxy.
|
||||
.ipc()
|
||||
->EnableNetworkProxyServer();
|
||||
.set_cwd("/");
|
||||
executor
|
||||
->limits()
|
||||
// Remove restrictions on the size of address-space of sandboxed
|
||||
|
|
|
@ -17,16 +17,12 @@
|
|||
#include "sandboxed_api/sandbox2/ipc.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <thread> // NOLINT(build/c++11)
|
||||
#include <thread>
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include "absl/memory/memory.h"
|
||||
#include "sandboxed_api/sandbox2/logserver.h"
|
||||
#include "sandboxed_api/sandbox2/logsink.h"
|
||||
#include "sandboxed_api/sandbox2/network_proxy_client.h"
|
||||
#include "sandboxed_api/sandbox2/network_proxy_server.h"
|
||||
|
||||
namespace sandbox2 {
|
||||
|
||||
|
@ -103,16 +99,4 @@ void IPC::EnableLogServer() {
|
|||
log_thread.detach();
|
||||
}
|
||||
|
||||
void IPC::EnableNetworkProxyServer() {
|
||||
int fd = ReceiveFd(NetworkProxyClient::kFDName);
|
||||
|
||||
auto proxy_server = [fd]() {
|
||||
NetworkProxyServer network_proxy_server(fd);
|
||||
network_proxy_server.Run();
|
||||
};
|
||||
|
||||
std::thread proxy_thread{proxy_server};
|
||||
proxy_thread.detach();
|
||||
}
|
||||
|
||||
} // namespace sandbox2
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/macros.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "sandboxed_api/sandbox2/comms.h"
|
||||
|
||||
|
@ -60,10 +59,6 @@ class IPC final {
|
|||
// Client::SendLogsToSupervisor in the sandboxee.
|
||||
void EnableLogServer();
|
||||
|
||||
// Enable network proxy server, this will start a thread in the sandbox
|
||||
// that waits for connection requests from the sandboxee.
|
||||
void EnableNetworkProxyServer();
|
||||
|
||||
private:
|
||||
friend class Executor;
|
||||
friend class Monitor;
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "sandboxed_api/sandbox2/limits.h"
|
||||
#include "sandboxed_api/sandbox2/mounts.h"
|
||||
#include "sandboxed_api/sandbox2/namespace.h"
|
||||
#include "sandboxed_api/sandbox2/network_proxy/server.h"
|
||||
#include "sandboxed_api/sandbox2/policy.h"
|
||||
#include "sandboxed_api/sandbox2/regs.h"
|
||||
#include "sandboxed_api/sandbox2/result.h"
|
||||
|
@ -140,6 +141,9 @@ Monitor::~Monitor() {
|
|||
if (log_file_) {
|
||||
std::fclose(log_file_);
|
||||
}
|
||||
if (network_proxy_server_) {
|
||||
network_proxy_thread_.join();
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -198,6 +202,10 @@ void Monitor::Run() {
|
|||
// sandbox master/monitor, which ptrace_attach'es to the child.
|
||||
int clone_flags = CLONE_UNTRACED;
|
||||
|
||||
if (policy_->allowed_hosts_) {
|
||||
EnableNetworkProxyServer();
|
||||
}
|
||||
|
||||
// Get PID of the sandboxee.
|
||||
pid_t init_pid = 0;
|
||||
Namespace* ns = policy_->GetNamespace();
|
||||
|
@ -349,6 +357,14 @@ void Monitor::MainLoop(sigset_t* sset) {
|
|||
KillSandboxee();
|
||||
}
|
||||
|
||||
if (network_proxy_server_ &&
|
||||
network_proxy_server_->violation_occurred_.load(
|
||||
std::memory_order_acquire) &&
|
||||
!network_violation_) {
|
||||
network_violation_ = true;
|
||||
KillSandboxee();
|
||||
}
|
||||
|
||||
// It should be a non-blocking operation (hence WNOHANG), so this function
|
||||
// returns quickly if there are no events to be processed.
|
||||
// Prioritize main pid to avoid resource starvation
|
||||
|
@ -401,7 +417,10 @@ void Monitor::MainLoop(sigset_t* sset) {
|
|||
VLOG(1) << "PID: " << ret << " terminated with signal: "
|
||||
<< util::GetSignalName(WTERMSIG(status));
|
||||
if (ret == pid_) {
|
||||
if (external_kill_) {
|
||||
if (network_violation_) {
|
||||
SetExitStatusCode(Result::NETWORK_VIOLATION, 0);
|
||||
result_.SetNetworkViolation(network_proxy_server_->violation_msg_);
|
||||
} else if (external_kill_) {
|
||||
SetExitStatusCode(Result::EXTERNAL_KILL, 0);
|
||||
} else if (timed_out_) {
|
||||
SetExitStatusCode(Result::TIMEOUT, 0);
|
||||
|
@ -794,7 +813,10 @@ void Monitor::EventPtraceExit(pid_t pid, int event_msg) {
|
|||
// 3) Regular signal/other exit cause.
|
||||
if (pid == pid_) {
|
||||
VLOG(1) << "PID: " << pid << " main special exit";
|
||||
if (external_kill_) {
|
||||
if (network_violation_) {
|
||||
SetExitStatusCode(Result::NETWORK_VIOLATION, 0);
|
||||
result_.SetNetworkViolation(network_proxy_server_->violation_msg_);
|
||||
} else if (external_kill_) {
|
||||
SetExitStatusCode(Result::EXTERNAL_KILL, 0);
|
||||
} else if (timed_out_) {
|
||||
SetExitStatusCode(Result::TIMEOUT, 0);
|
||||
|
@ -926,4 +948,14 @@ void Monitor::LogSyscallViolationExplanation(const Syscall& syscall) const {
|
|||
}
|
||||
}
|
||||
|
||||
void Monitor::EnableNetworkProxyServer() {
|
||||
int fd = ipc_->ReceiveFd(NetworkProxyClient::kFDName);
|
||||
|
||||
network_proxy_server_ = absl::make_unique<NetworkProxyServer>(
|
||||
fd, &policy_->allowed_hosts_.value(), pthread_self());
|
||||
|
||||
network_proxy_thread_ = std::thread(&NetworkProxyServer::Run,
|
||||
network_proxy_server_.get());
|
||||
}
|
||||
|
||||
} // namespace sandbox2
|
||||
|
|
|
@ -26,11 +26,13 @@
|
|||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
#include "absl/synchronization/notification.h"
|
||||
#include "sandboxed_api/sandbox2/comms.h"
|
||||
#include "sandboxed_api/sandbox2/executor.h"
|
||||
#include "sandboxed_api/sandbox2/ipc.h"
|
||||
#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"
|
||||
|
@ -139,6 +141,10 @@ class Monitor final {
|
|||
// Processes stop path.
|
||||
void EventPtraceStop(pid_t pid, int stopsig);
|
||||
|
||||
// Enable network proxy server, this will start a thread in the sandbox
|
||||
// that waits for connection requests from the sandboxee.
|
||||
void EnableNetworkProxyServer();
|
||||
|
||||
// Internal objects, owned by the Sandbox2 object.
|
||||
Executor* executor_;
|
||||
Notify* notify_;
|
||||
|
@ -168,6 +174,8 @@ class Monitor final {
|
|||
std::atomic<int64_t> deadline_millis_{0};
|
||||
// Was external kill sent to the sandboxee
|
||||
bool external_kill_ = false;
|
||||
// Network violation occurred and process of killing sandboxee started
|
||||
bool network_violation_ = false;
|
||||
// Is the sandboxee timed out
|
||||
bool timed_out_ = false;
|
||||
// Should we dump the main sandboxed PID's stack?
|
||||
|
@ -178,6 +186,12 @@ class Monitor final {
|
|||
// Log file specified by
|
||||
// --sandbox_danger_danger_permit_all_and_log flag.
|
||||
FILE* log_file_ = nullptr;
|
||||
|
||||
// Handle to the class responsible for proxying and validating connect()
|
||||
// requests.
|
||||
std::unique_ptr<NetworkProxyServer> network_proxy_server_;
|
||||
|
||||
std::thread network_proxy_thread_;
|
||||
};
|
||||
|
||||
} // namespace sandbox2
|
||||
|
|
|
@ -1,217 +0,0 @@
|
|||
// Copyright 2019 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "sandboxed_api/sandbox2/network_proxy_client.h"
|
||||
|
||||
#include <linux/net.h>
|
||||
#include <linux/seccomp.h>
|
||||
#include <stdio.h>
|
||||
#include <syscall.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#include <cerrno>
|
||||
#include <iostream>
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||
#include "sandboxed_api/util/canonical_errors.h"
|
||||
#include "sandboxed_api/util/status.h"
|
||||
#include "sandboxed_api/util/status_macros.h"
|
||||
|
||||
namespace sandbox2 {
|
||||
|
||||
#ifndef SYS_SECCOMP
|
||||
constexpr int SYS_SECCOMP = 1;
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64__)
|
||||
constexpr int kRegResult = REG_RAX;
|
||||
constexpr int kRegSyscall = REG_RAX;
|
||||
constexpr int kRegArg0 = REG_RDI;
|
||||
constexpr int kRegArg1 = REG_RSI;
|
||||
constexpr int kRegArg2 = REG_RDX;
|
||||
#endif
|
||||
#if defined(__powerpc64__)
|
||||
constexpr int kRegResult = 3;
|
||||
constexpr int kRegSyscall = 0;
|
||||
constexpr int kRegArg0 = 3;
|
||||
constexpr int kRegArg1 = 4;
|
||||
constexpr int kRegArg2 = 5;
|
||||
#endif
|
||||
|
||||
constexpr char NetworkProxyClient::kFDName[];
|
||||
|
||||
int NetworkProxyClient::ConnectHandler(int sockfd, const struct sockaddr* addr,
|
||||
socklen_t addrlen) {
|
||||
sapi::Status status = Connect(sockfd, addr, addrlen);
|
||||
if (status.ok()) {
|
||||
return 0;
|
||||
}
|
||||
LOG(ERROR) << "ConnectHandler() failed: " << status.message();
|
||||
return -1;
|
||||
}
|
||||
|
||||
sapi::Status NetworkProxyClient::Connect(int sockfd,
|
||||
const struct sockaddr* addr,
|
||||
socklen_t addrlen) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
|
||||
// Check if socket is SOCK_STREAM
|
||||
int type;
|
||||
socklen_t type_size = sizeof(int);
|
||||
int result = getsockopt(sockfd, SOL_SOCKET, SO_TYPE, &type, &type_size);
|
||||
if (result == -1) {
|
||||
return sapi::FailedPreconditionError("Invalid socket FD");
|
||||
}
|
||||
if (type_size != sizeof(int) || type != SOCK_STREAM) {
|
||||
errno = EINVAL;
|
||||
return sapi::InvalidArgumentError(
|
||||
"Invalid socket, only SOCK_STREAM is allowed");
|
||||
}
|
||||
|
||||
// Send sockaddr struct
|
||||
if (!comms_.SendBytes(reinterpret_cast<const uint8_t*>(addr), addrlen)) {
|
||||
errno = EIO;
|
||||
return sapi::InternalError("Sending data to network proxy failed");
|
||||
}
|
||||
|
||||
SAPI_RETURN_IF_ERROR(ReceiveRemoteResult());
|
||||
|
||||
// Receive new socket
|
||||
int s;
|
||||
if (!comms_.RecvFD(&s)) {
|
||||
errno = EIO;
|
||||
return sapi::InternalError("Receiving data from network proxy failed");
|
||||
}
|
||||
if (dup2(s, sockfd) == -1) {
|
||||
close(s);
|
||||
return sapi::InternalError("Processing data from network proxy failed");
|
||||
}
|
||||
return sapi::OkStatus();
|
||||
}
|
||||
|
||||
sapi::Status NetworkProxyClient::ReceiveRemoteResult() {
|
||||
int result;
|
||||
if (!comms_.RecvInt32(&result)) {
|
||||
errno = EIO;
|
||||
return sapi::InternalError("Receiving data from the network proxy failed");
|
||||
}
|
||||
if (result != 0) {
|
||||
errno = result;
|
||||
return sapi::InternalError(
|
||||
absl::StrCat("Error in network proxy server: ", StrError(errno)));
|
||||
}
|
||||
return sapi::OkStatus();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
static NetworkProxyHandler* g_network_proxy_handler = nullptr;
|
||||
|
||||
void SignalHandler(int nr, siginfo_t* info, void* void_context) {
|
||||
g_network_proxy_handler->ProcessSeccompTrap(nr, info, void_context);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
sapi::Status NetworkProxyHandler::InstallNetworkProxyHandler(
|
||||
NetworkProxyClient* npc) {
|
||||
if (g_network_proxy_handler) {
|
||||
return sapi::AlreadyExistsError(
|
||||
"Network proxy handler is already installed");
|
||||
}
|
||||
g_network_proxy_handler = new NetworkProxyHandler(npc);
|
||||
return sapi::OkStatus();
|
||||
}
|
||||
|
||||
void NetworkProxyHandler::InvokeOldAct(int nr, siginfo_t* info,
|
||||
void* void_context) {
|
||||
if (oldact_.sa_flags & SA_SIGINFO) {
|
||||
if (oldact_.sa_sigaction) {
|
||||
oldact_.sa_sigaction(nr, info, void_context);
|
||||
}
|
||||
} else if (oldact_.sa_handler == SIG_IGN) {
|
||||
return;
|
||||
} else if (oldact_.sa_handler == SIG_DFL) {
|
||||
sigaction(SIGSYS, &oldact_, nullptr);
|
||||
raise(SIGSYS);
|
||||
} else if (oldact_.sa_handler) {
|
||||
oldact_.sa_handler(nr);
|
||||
}
|
||||
} // namespace sandbox2
|
||||
|
||||
void NetworkProxyHandler::ProcessSeccompTrap(int nr, siginfo_t* info,
|
||||
void* void_context) {
|
||||
ucontext_t* ctx = (ucontext_t*)(void_context);
|
||||
if (info->si_code != SYS_SECCOMP) {
|
||||
InvokeOldAct(nr, info, void_context);
|
||||
return;
|
||||
}
|
||||
if (!ctx) return;
|
||||
|
||||
#if defined(__x86_64__)
|
||||
auto* registers = ctx->uc_mcontext.gregs;
|
||||
#elif defined(__powerpc64__)
|
||||
auto* registers = ctx->uc_mcontext.gp_regs;
|
||||
using ppc_gpreg_t = std::decay<decltype(registers[0])>::type;
|
||||
#endif
|
||||
|
||||
int syscall = registers[kRegSyscall];
|
||||
|
||||
int sockfd;
|
||||
const struct sockaddr* addr;
|
||||
socklen_t addrlen;
|
||||
|
||||
if (syscall == __NR_connect) {
|
||||
sockfd = static_cast<int>(registers[kRegArg0]);
|
||||
addr = reinterpret_cast<const struct sockaddr*>(registers[kRegArg1]);
|
||||
addrlen = static_cast<socklen_t>(registers[kRegArg2]);
|
||||
#if defined(__powerpc64__)
|
||||
} else if (syscall == __NR_socketcall &&
|
||||
static_cast<int>(registers[kRegArg0]) == SYS_CONNECT) {
|
||||
ppc_gpreg_t* args = reinterpret_cast<ppc_gpreg_t*>(registers[kRegArg1]);
|
||||
|
||||
sockfd = static_cast<int>(args[0]);
|
||||
addr = reinterpret_cast<const struct sockaddr*>(args[1]);
|
||||
addrlen = static_cast<socklen_t>(args[2]);
|
||||
#endif
|
||||
} else {
|
||||
InvokeOldAct(nr, info, void_context);
|
||||
return;
|
||||
}
|
||||
|
||||
sapi::Status result = network_proxy_client_->Connect(sockfd, addr, addrlen);
|
||||
if (result.ok()) {
|
||||
registers[kRegResult] = 0;
|
||||
} else {
|
||||
registers[kRegResult] = -errno;
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkProxyHandler::InstallSeccompTrap() {
|
||||
sigset_t mask;
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGSYS);
|
||||
|
||||
struct sigaction act = {};
|
||||
act.sa_sigaction = &SignalHandler;
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
|
||||
CHECK_EQ(sigaction(SIGSYS, &act, &oldact_), 0);
|
||||
CHECK_EQ(sigprocmask(SIG_UNBLOCK, &mask, nullptr), 0);
|
||||
}
|
||||
|
||||
} // namespace sandbox2
|
|
@ -1,75 +0,0 @@
|
|||
// Copyright 2019 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SANDBOXED_API_SANDBOX2_NETWORK_PROXY_CLIENT_H_
|
||||
#define SANDBOXED_API_SANDBOX2_NETWORK_PROXY_CLIENT_H_
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "sandboxed_api/sandbox2/comms.h"
|
||||
#include "sandboxed_api/util/status.h"
|
||||
|
||||
namespace sandbox2 {
|
||||
|
||||
class NetworkProxyClient {
|
||||
public:
|
||||
static constexpr char kFDName[] = "sb2_networkproxy";
|
||||
|
||||
explicit NetworkProxyClient(int fd) : comms_(fd) {}
|
||||
|
||||
NetworkProxyClient(const NetworkProxyClient&) = delete;
|
||||
NetworkProxyClient& operator=(const NetworkProxyClient&) = delete;
|
||||
|
||||
// Establishes a new network connection.
|
||||
// Semantic is similar to a regular connect() call.
|
||||
// Arguments are sent to network proxy server, which sends back a connected
|
||||
// socket.
|
||||
sapi::Status Connect(int sockfd, const struct sockaddr* addr,
|
||||
socklen_t addrlen);
|
||||
// Same as Connect, but with same API as regular connect() call.
|
||||
int ConnectHandler(int sockfd, const struct sockaddr* addr,
|
||||
socklen_t addrlen);
|
||||
|
||||
private:
|
||||
Comms comms_;
|
||||
sapi::Status ReceiveRemoteResult();
|
||||
|
||||
// Needed to make the Proxy thread safe.
|
||||
absl::Mutex mutex_;
|
||||
};
|
||||
|
||||
class NetworkProxyHandler {
|
||||
public:
|
||||
// Installs the handler that redirects connect() syscalls to the trap
|
||||
// function. This function exchange data with NetworkProxyServer that checks
|
||||
// if this connection is allowed and sends the connected socket to us.
|
||||
// In other words, this function just use NetworkProxyClient class.
|
||||
static sapi::Status InstallNetworkProxyHandler(NetworkProxyClient* npc);
|
||||
void ProcessSeccompTrap(int nr, siginfo_t* info, void* void_context);
|
||||
|
||||
private:
|
||||
NetworkProxyHandler(NetworkProxyClient* npc) : network_proxy_client_(npc) {
|
||||
InstallSeccompTrap();
|
||||
}
|
||||
void InvokeOldAct(int nr, siginfo_t* info, void* void_context);
|
||||
void InstallSeccompTrap();
|
||||
|
||||
struct sigaction oldact_;
|
||||
NetworkProxyClient* network_proxy_client_;
|
||||
};
|
||||
|
||||
} // namespace sandbox2
|
||||
|
||||
#endif // SANDBOXED_API_SANDBOX2_NETWORK_PROXY_CLIENT_H_
|
|
@ -1,95 +0,0 @@
|
|||
// Copyright 2019 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "sandboxed_api/sandbox2/network_proxy_server.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <syscall.h>
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include "absl/memory/memory.h"
|
||||
#include "sandboxed_api/sandbox2/util/fileops.h"
|
||||
|
||||
namespace sandbox2 {
|
||||
|
||||
NetworkProxyServer::NetworkProxyServer(int fd)
|
||||
: comms_{absl::make_unique<Comms>(fd)}, fatal_error_{false} {}
|
||||
|
||||
void NetworkProxyServer::ProcessConnectRequest() {
|
||||
std::vector<uint8_t> addr;
|
||||
if (!comms_->RecvBytes(&addr)) {
|
||||
fatal_error_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const struct sockaddr_in* saddr =
|
||||
reinterpret_cast<const sockaddr_in*>(addr.data());
|
||||
|
||||
// Only IPv4 TCP and IPv6 TCP are supported.
|
||||
if (!((addr.size() == sizeof(sockaddr_in) && saddr->sin_family == AF_INET) ||
|
||||
(addr.size() == sizeof(sockaddr_in6) &&
|
||||
saddr->sin_family == AF_INET6))) {
|
||||
SendError(EINVAL);
|
||||
return;
|
||||
}
|
||||
|
||||
int new_socket = socket(saddr->sin_family, SOCK_STREAM, 0);
|
||||
if (new_socket < 0) {
|
||||
SendError(errno);
|
||||
return;
|
||||
}
|
||||
|
||||
file_util::fileops::FDCloser new_socket_closer(new_socket);
|
||||
|
||||
int result = connect(
|
||||
new_socket, reinterpret_cast<const sockaddr*>(addr.data()), addr.size());
|
||||
|
||||
if (result == 0) {
|
||||
NotifySuccess();
|
||||
if (!fatal_error_) {
|
||||
if (!comms_->SendFD(new_socket)) {
|
||||
fatal_error_ = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkProxyServer::Run() {
|
||||
while (!fatal_error_) {
|
||||
ProcessConnectRequest();
|
||||
}
|
||||
LOG(INFO)
|
||||
<< "Clean shutdown or error occurred, shutting down NetworkProxyServer";
|
||||
}
|
||||
|
||||
void NetworkProxyServer::SendError(int saved_errno) {
|
||||
if (!comms_->SendInt32(saved_errno)) {
|
||||
fatal_error_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkProxyServer::NotifySuccess() {
|
||||
if (!comms_->SendInt32(0)) {
|
||||
fatal_error_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sandbox2
|
|
@ -1,53 +0,0 @@
|
|||
// Copyright 2019 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SANDBOXED_API_SANDBOX2_NETWORK_PROXY_SERVER_H_
|
||||
#define SANDBOXED_API_SANDBOX2_NETWORK_PROXY_SERVER_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "sandboxed_api/sandbox2/comms.h"
|
||||
|
||||
namespace sandbox2 {
|
||||
|
||||
// This is a proxy server that spawns connected sockets on requests.
|
||||
// Then it sends the file descriptor to the requestor. It is used to get around
|
||||
// limitations created by network namespaces.
|
||||
class NetworkProxyServer {
|
||||
public:
|
||||
explicit NetworkProxyServer(int fd);
|
||||
|
||||
NetworkProxyServer(const NetworkProxyServer&) = delete;
|
||||
NetworkProxyServer& operator=(const NetworkProxyServer&) = delete;
|
||||
|
||||
// Starts handling incoming connection requests.
|
||||
void Run();
|
||||
|
||||
private:
|
||||
// Notifies the network proxy client about the error and sends its code.
|
||||
void SendError(int saved_errno);
|
||||
|
||||
// Notifies the network proxy client that no error occurred.
|
||||
void NotifySuccess();
|
||||
|
||||
// Serves connection requests from the network proxy client.
|
||||
void ProcessConnectRequest();
|
||||
|
||||
std::unique_ptr<Comms> comms_;
|
||||
bool fatal_error_;
|
||||
};
|
||||
|
||||
} // namespace sandbox2
|
||||
|
||||
#endif // SANDBOXED_API_SANDBOX2_NETWORK_PROXY_SERVER_H_
|
|
@ -31,6 +31,7 @@
|
|||
#include "absl/base/macros.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "sandboxed_api/sandbox2/namespace.h"
|
||||
#include "sandboxed_api/sandbox2/network_proxy/filtering.h"
|
||||
#include "sandboxed_api/sandbox2/syscall.h"
|
||||
#include "sandboxed_api/sandbox2/violation.pb.h"
|
||||
|
||||
|
@ -104,6 +105,9 @@ class Policy final {
|
|||
// Get a policy which would allow the Monitor module to track all syscalls.
|
||||
std::vector<sock_filter> GetTrackingPolicy() const;
|
||||
|
||||
// Contains a list of hosts the sandboxee is allowed to connect to.
|
||||
absl::optional<AllowedHosts> allowed_hosts_;
|
||||
|
||||
friend class Monitor;
|
||||
friend class PolicyBuilder;
|
||||
friend class PolicyBuilderPeer; // For testing
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "sandboxed_api/sandbox2/namespace.h"
|
||||
#include "sandboxed_api/sandbox2/util/bpf_helper.h"
|
||||
#include "sandboxed_api/sandbox2/util/path.h"
|
||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||
#include "sandboxed_api/util/canonical_errors.h"
|
||||
#include "sandboxed_api/util/status_macros.h"
|
||||
|
||||
|
@ -47,7 +48,7 @@ namespace {
|
|||
|
||||
} // namespace
|
||||
|
||||
PolicyBuilder& PolicyBuilder::AllowSyscall(unsigned int num) {
|
||||
PolicyBuilder& PolicyBuilder::AllowSyscall(uint32_t num) {
|
||||
if (handled_syscalls_.insert(num).second) {
|
||||
user_policy_.insert(user_policy_.end(), {SYSCALL(num, ALLOW)});
|
||||
}
|
||||
|
@ -68,8 +69,7 @@ PolicyBuilder& PolicyBuilder::AllowSyscalls(SyscallInitializer nums) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
PolicyBuilder& PolicyBuilder::BlockSyscallWithErrno(unsigned int num,
|
||||
int error) {
|
||||
PolicyBuilder& PolicyBuilder::BlockSyscallWithErrno(uint32_t num, int error) {
|
||||
if (handled_syscalls_.insert(num).second) {
|
||||
user_policy_.insert(user_policy_.end(), {SYSCALL(num, ERRNO(error))});
|
||||
}
|
||||
|
@ -545,17 +545,17 @@ PolicyBuilder& PolicyBuilder::AllowDynamicStartup() {
|
|||
});
|
||||
}
|
||||
|
||||
PolicyBuilder& PolicyBuilder::AddPolicyOnSyscall(unsigned int num,
|
||||
PolicyBuilder& PolicyBuilder::AddPolicyOnSyscall(uint32_t num,
|
||||
BpfInitializer policy) {
|
||||
return AddPolicyOnSyscalls({num}, policy);
|
||||
}
|
||||
|
||||
PolicyBuilder& PolicyBuilder::AddPolicyOnSyscall(
|
||||
unsigned int num, const std::vector<sock_filter>& policy) {
|
||||
uint32_t num, const std::vector<sock_filter>& policy) {
|
||||
return AddPolicyOnSyscalls({num}, policy);
|
||||
}
|
||||
|
||||
PolicyBuilder& PolicyBuilder::AddPolicyOnSyscall(unsigned int num, BpfFunc f) {
|
||||
PolicyBuilder& PolicyBuilder::AddPolicyOnSyscall(uint32_t num, BpfFunc f) {
|
||||
return AddPolicyOnSyscalls({num}, f);
|
||||
}
|
||||
|
||||
|
@ -700,6 +700,7 @@ sapi::StatusOr<std::unique_ptr<Policy>> PolicyBuilder::TryBuild() {
|
|||
|
||||
StoreDescription(pb_description.get());
|
||||
output->policy_builder_description_ = std::move(pb_description);
|
||||
output->allowed_hosts_ = std::move(allowed_hosts_);
|
||||
already_built_ = true;
|
||||
return std::move(output);
|
||||
}
|
||||
|
@ -848,6 +849,15 @@ PolicyBuilder& PolicyBuilder::CollectStacktracesOnKill(bool enable) {
|
|||
}
|
||||
|
||||
PolicyBuilder& PolicyBuilder::AddNetworkProxyPolicy() {
|
||||
if (allowed_hosts_) {
|
||||
SetError(sapi::FailedPreconditionError(
|
||||
"AddNetworkProxyPolicy or AddNetworkProxyHandlerPolicy can be called "
|
||||
"at most once"));
|
||||
return *this;
|
||||
}
|
||||
|
||||
allowed_hosts_ = AllowedHosts();
|
||||
|
||||
AllowFutexOp(FUTEX_WAKE);
|
||||
AllowFutexOp(FUTEX_WAIT);
|
||||
AllowFutexOp(FUTEX_WAIT_BITSET);
|
||||
|
@ -920,4 +930,36 @@ void PolicyBuilder::StoreDescription(PolicyBuilderDescription* pb_description) {
|
|||
}
|
||||
}
|
||||
|
||||
PolicyBuilder& PolicyBuilder::AllowIPv4(const std::string& ip_and_mask,
|
||||
uint32_t port) {
|
||||
if (!allowed_hosts_) {
|
||||
SetError(sapi::FailedPreconditionError(
|
||||
"AddNetworkProxyPolicy or AddNetworkProxyHandlerPolicy must be called "
|
||||
"before adding IP rules"));
|
||||
return *this;
|
||||
}
|
||||
|
||||
sapi::Status status = allowed_hosts_->AllowIPv4(ip_and_mask, port);
|
||||
if (!status.ok()) {
|
||||
SetError(status);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
PolicyBuilder& PolicyBuilder::AllowIPv6(const std::string& ip_and_mask,
|
||||
uint32_t port) {
|
||||
if (!allowed_hosts_) {
|
||||
SetError(sapi::FailedPreconditionError(
|
||||
"AddNetworkProxyPolicy or AddNetworkProxyHandlerPolicy must be called "
|
||||
"before adding IP rules"));
|
||||
return *this;
|
||||
}
|
||||
|
||||
sapi::Status status = allowed_hosts_->AllowIPv6(ip_and_mask, port);
|
||||
if (!status.ok()) {
|
||||
SetError(status);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace sandbox2
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "absl/memory/memory.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "sandboxed_api/sandbox2/mounts.h"
|
||||
#include "sandboxed_api/sandbox2/network_proxy/filtering.h"
|
||||
#include "sandboxed_api/sandbox2/policy.h"
|
||||
#include "sandboxed_api/util/statusor.h"
|
||||
|
||||
|
@ -501,6 +502,10 @@ class PolicyBuilder final {
|
|||
// Not recommended
|
||||
PolicyBuilder& SetRootWritable();
|
||||
|
||||
// Allows connections to this IP.
|
||||
PolicyBuilder& AllowIPv4(const std::string& ip_and_mask, uint32_t port = 0);
|
||||
PolicyBuilder& AllowIPv6(const std::string& ip_and_mask, uint32_t port = 0);
|
||||
|
||||
private:
|
||||
friend class PolicyBuilderPeer; // For testing
|
||||
friend class StackTracePeer;
|
||||
|
@ -542,6 +547,9 @@ class PolicyBuilder final {
|
|||
// This function returns a PolicyBuilder so that we can use it in the status
|
||||
// macros
|
||||
PolicyBuilder& SetError(const sapi::Status& status);
|
||||
|
||||
// Contains list of allowed hosts.
|
||||
absl::optional<AllowedHosts> allowed_hosts_;
|
||||
};
|
||||
|
||||
} // namespace sandbox2
|
||||
|
|
|
@ -79,6 +79,10 @@ std::string Result::ToString() const {
|
|||
Syscall(GetSyscallArch(), reason_code()).GetName(),
|
||||
"] Stack: ", GetStackTrace());
|
||||
break;
|
||||
case sandbox2::Result::NETWORK_VIOLATION:
|
||||
result = absl::StrCat("NETWORK VIOLATION - Violating network policy: ",
|
||||
network_violation_);
|
||||
break;
|
||||
case sandbox2::Result::SIGNALED:
|
||||
result = absl::StrCat("Process terminated with a SIGNAL - Signal: ",
|
||||
util::GetSignalName(reason_code()),
|
||||
|
@ -129,6 +133,8 @@ std::string Result::StatusEnumToString(StatusEnum value) {
|
|||
return "SETUP_ERROR";
|
||||
case sandbox2::Result::VIOLATION:
|
||||
return "VIOLATION";
|
||||
case sandbox2::Result::NETWORK_VIOLATION:
|
||||
return "NETWORK_VIOLATION";
|
||||
case sandbox2::Result::SIGNALED:
|
||||
return "SIGNALED";
|
||||
case sandbox2::Result::TIMEOUT:
|
||||
|
|
|
@ -45,6 +45,8 @@ class Result {
|
|||
SETUP_ERROR,
|
||||
// Syscall violation
|
||||
VIOLATION,
|
||||
// Network policy violation
|
||||
NETWORK_VIOLATION,
|
||||
// Process terminated with a signal
|
||||
SIGNALED,
|
||||
// Process terminated with a timeout
|
||||
|
@ -119,6 +121,10 @@ class Result {
|
|||
syscall_ = std::move(syscall);
|
||||
}
|
||||
|
||||
void SetNetworkViolation(std::string network_violation) {
|
||||
network_violation_ = std::move(network_violation);
|
||||
}
|
||||
|
||||
StatusEnum final_status() const { return final_status_; }
|
||||
uintptr_t reason_code() const { return reason_code_; }
|
||||
|
||||
|
@ -137,6 +143,8 @@ class Result {
|
|||
|
||||
const std::string& GetProgName() const { return prog_name_; }
|
||||
|
||||
const std::string& GetNetworkViolation() const { return network_violation_; }
|
||||
|
||||
void SetProgName(const std::string& name) { prog_name_ = name; }
|
||||
|
||||
const std::string& GetProcMaps() const { return proc_maps_; }
|
||||
|
@ -179,6 +187,8 @@ class Result {
|
|||
std::string prog_name_;
|
||||
// /proc/pid/maps of the main process.
|
||||
std::string proc_maps_;
|
||||
// IP and port if network violation occurred
|
||||
std::string network_violation_;
|
||||
// Final resource usage as defined in <sys/resource.h> (man getrusage), for
|
||||
// the Monitor thread.
|
||||
rusage rusage_monitor_;
|
||||
|
|
Loading…
Reference in New Issue
Block a user