diff --git a/sandboxed_api/sandbox2/network_proxy/BUILD.bazel b/sandboxed_api/sandbox2/network_proxy/BUILD.bazel index 684cfb2..22421c3 100644 --- a/sandboxed_api/sandbox2/network_proxy/BUILD.bazel +++ b/sandboxed_api/sandbox2/network_proxy/BUILD.bazel @@ -43,11 +43,10 @@ cc_library( copts = sapi_platform_copts(), visibility = ["//visibility:public"], deps = [ - "//sandboxed_api:config", "//sandboxed_api/sandbox2:comms", + "//sandboxed_api/sandbox2/util:syscall_trap", "//sandboxed_api/util:status", "@com_google_absl//absl/log", - "@com_google_absl//absl/log:check", "@com_google_absl//absl/status", "@com_google_absl//absl/synchronization", ], diff --git a/sandboxed_api/sandbox2/network_proxy/CMakeLists.txt b/sandboxed_api/sandbox2/network_proxy/CMakeLists.txt index 7d86c40..75bfba3 100644 --- a/sandboxed_api/sandbox2/network_proxy/CMakeLists.txt +++ b/sandboxed_api/sandbox2/network_proxy/CMakeLists.txt @@ -49,12 +49,11 @@ add_library(sandbox2_network_proxy_client ${SAPI_LIB_TYPE} ) add_library(sandbox2::network_proxy_client ALIAS sandbox2_network_proxy_client) target_link_libraries(sandbox2_network_proxy_client PRIVATE - absl::check absl::strings absl::synchronization absl::log sandbox2::comms - sapi::config + sandbox2::syscall_trap sapi::strerror sapi::base sapi::status diff --git a/sandboxed_api/sandbox2/network_proxy/client.cc b/sandboxed_api/sandbox2/network_proxy/client.cc index 1f5a239..46fe6c2 100644 --- a/sandboxed_api/sandbox2/network_proxy/client.cc +++ b/sandboxed_api/sandbox2/network_proxy/client.cc @@ -18,50 +18,18 @@ #include #include #include -#include #include #include #include -#include "absl/log/check.h" #include "absl/log/log.h" #include "absl/status/status.h" -#include "sandboxed_api/config.h" +#include "sandboxed_api/sandbox2/util/syscall_trap.h" #include "sandboxed_api/util/status_macros.h" namespace sandbox2 { -#ifndef SYS_SECCOMP -constexpr int SYS_SECCOMP = 1; -#endif - -#if defined(SAPI_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; -#elif defined(SAPI_PPC64_LE) -constexpr int kRegResult = 3; -constexpr int kRegSyscall = 0; -constexpr int kRegArg0 = 3; -constexpr int kRegArg1 = 4; -constexpr int kRegArg2 = 5; -#elif defined(SAPI_ARM64) -constexpr int kRegResult = 0; -constexpr int kRegSyscall = 8; -constexpr int kRegArg0 = 0; -constexpr int kRegArg1 = 1; -constexpr int kRegArg2 = 2; -#elif defined(SAPI_ARM) -constexpr int kRegResult = 0; -constexpr int kRegSyscall = 8; -constexpr int kRegArg0 = 0; -constexpr int kRegArg1 = 1; -constexpr int kRegArg2 = 2; -#endif - int NetworkProxyClient::ConnectHandler(int sockfd, const struct sockaddr* addr, socklen_t addrlen) { absl::Status status = Connect(sockfd, addr, addrlen); @@ -124,104 +92,52 @@ absl::Status NetworkProxyClient::ReceiveRemoteResult() { return absl::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 +NetworkProxyClient* NetworkProxyHandler::network_proxy_client_ = nullptr; absl::Status NetworkProxyHandler::InstallNetworkProxyHandler( NetworkProxyClient* npc) { - if (g_network_proxy_handler) { + if (network_proxy_client_ != nullptr) { return absl::AlreadyExistsError( "Network proxy handler is already installed"); } - g_network_proxy_handler = new NetworkProxyHandler(npc); + network_proxy_client_ = npc; + if (!SyscallTrap::Install([](int nr, SyscallTrap::Args args, uintptr_t* rv) { + return ProcessSeccompTrap(nr, args, rv); + })) { + return absl::InternalError("Could not install syscall trap"); + } return absl::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) { - if (info->si_code != SYS_SECCOMP) { - InvokeOldAct(nr, info, void_context); - return; - } - auto* ctx = static_cast(void_context); - if (!ctx) { - return; - } - -#if defined(SAPI_X86_64) - auto* registers = ctx->uc_mcontext.gregs; -#elif defined(SAPI_PPC64_LE) - auto* registers = ctx->uc_mcontext.gp_regs; -#elif defined(SAPI_ARM64) - auto* registers = ctx->uc_mcontext.regs; -#elif defined(SAPI_ARM) - auto* registers = &ctx->uc_mcontext.arm_r0; -#endif - int syscall = registers[kRegSyscall]; - +bool NetworkProxyHandler::ProcessSeccompTrap(int nr, SyscallTrap::Args args, + uintptr_t* rv) { int sockfd; const struct sockaddr* addr; socklen_t addrlen; - if (syscall == __NR_connect) { - sockfd = static_cast(registers[kRegArg0]); - addr = reinterpret_cast(registers[kRegArg1]); - addrlen = static_cast(registers[kRegArg2]); + if (nr == __NR_connect) { + sockfd = static_cast(args[0]); + addr = reinterpret_cast(args[1]); + addrlen = static_cast(args[2]); #if defined(SAPI_PPC64_LE) - } else if (syscall == __NR_socketcall && - static_cast(registers[kRegArg0]) == SYS_CONNECT) { - auto* connect_args = reinterpret_cast(registers[kRegArg1]); + } else if (nr == __NR_socketcall && + static_cast(args[0]) == SYS_CONNECT) { + auto* connect_args = reinterpret_cast(args[1]); sockfd = static_cast(connect_args[0]); addr = reinterpret_cast(connect_args[1]); addrlen = static_cast(connect_args[2]); #endif } else { - InvokeOldAct(nr, info, void_context); - return; + return false; } absl::Status result = network_proxy_client_->Connect(sockfd, addr, addrlen); if (result.ok()) { - registers[kRegResult] = 0; + *rv = 0; } else { - registers[kRegResult] = -errno; + *rv = -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); + return true; } } // namespace sandbox2 diff --git a/sandboxed_api/sandbox2/network_proxy/client.h b/sandboxed_api/sandbox2/network_proxy/client.h index 19de027..70fa79d 100644 --- a/sandboxed_api/sandbox2/network_proxy/client.h +++ b/sandboxed_api/sandbox2/network_proxy/client.h @@ -16,11 +16,11 @@ #define SANDBOXED_API_SANDBOX2_NETWORK_PROXY_CLIENT_H_ #include -#include #include "absl/status/status.h" #include "absl/synchronization/mutex.h" #include "sandboxed_api/sandbox2/comms.h" +#include "sandboxed_api/sandbox2/util/syscall_trap.h" namespace sandbox2 { @@ -57,17 +57,9 @@ class NetworkProxyHandler { // if this connection is allowed and sends the connected socket to us. static absl::Status InstallNetworkProxyHandler(NetworkProxyClient* npc); - void ProcessSeccompTrap(int nr, siginfo_t* info, void* void_context); + static bool ProcessSeccompTrap(int nr, SyscallTrap::Args args, uintptr_t* rv); - 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_; + static NetworkProxyClient* network_proxy_client_; }; } // namespace sandbox2