diff --git a/sandboxed_api/sandbox2/BUILD.bazel b/sandboxed_api/sandbox2/BUILD.bazel index 3a08b88..0564e5d 100644 --- a/sandboxed_api/sandbox2/BUILD.bazel +++ b/sandboxed_api/sandbox2/BUILD.bazel @@ -244,6 +244,7 @@ cc_binary( ":comms", ":forkserver", ":sanitizer", + ":util", "//sandboxed_api/util:raw_logging", "//sandboxed_api/util:strerror", "@com_google_absl//absl/log:globals", @@ -266,6 +267,7 @@ cc_library( ":fork_client", ":forkserver_bin_embed", ":forkserver_cc_proto", + ":util", "//sandboxed_api:config", "//sandboxed_api:embed_file", "//sandboxed_api/util:fileops", diff --git a/sandboxed_api/sandbox2/CMakeLists.txt b/sandboxed_api/sandbox2/CMakeLists.txt index 87acb05..e4f5584 100644 --- a/sandboxed_api/sandbox2/CMakeLists.txt +++ b/sandboxed_api/sandbox2/CMakeLists.txt @@ -210,6 +210,7 @@ target_link_libraries(sandbox2_forkserver_bin PRIVATE sandbox2::comms sandbox2::forkserver sandbox2::sanitizer + sandbox2::util sapi::base sapi::raw_logging ) @@ -236,6 +237,7 @@ target_link_libraries(sandbox2_global_forkserver absl::log sandbox2::client sandbox2::forkserver_bin_embed + sandbox2::util sapi::strerror sapi::base sapi::config diff --git a/sandboxed_api/sandbox2/forkserver.cc b/sandboxed_api/sandbox2/forkserver.cc index 5f79c65..a11e593 100644 --- a/sandboxed_api/sandbox2/forkserver.cc +++ b/sandboxed_api/sandbox2/forkserver.cc @@ -61,6 +61,10 @@ #include "sandboxed_api/util/raw_logging.h" #include "sandboxed_api/util/strerror.h" +namespace sandbox2 { + +namespace file_util = ::sapi::file_util; + namespace { using ::sapi::StrError; @@ -244,10 +248,6 @@ bool IsLikelyChrooted() { } // namespace -namespace sandbox2 { - -namespace file_util = ::sapi::file_util; - void ForkServer::PrepareExecveArgs(const ForkRequest& request, std::vector* args, std::vector* envp) { @@ -616,11 +616,8 @@ void ForkServer::ExecuteProcess(int execve_fd, const char* const* argv, // Do not add any code before execve(), as it's subject to seccomp policies. // Indicate that it's a special execve(), by setting 4th, 5th and 6th syscall // argument to magic values. - util::Syscall( - __NR_execveat, static_cast(execve_fd), - reinterpret_cast(""), reinterpret_cast(argv), - reinterpret_cast(envp), static_cast(AT_EMPTY_PATH), - reinterpret_cast(internal::kExecveMagic)); + util::Execveat(execve_fd, "", argv, envp, AT_EMPTY_PATH, + internal::kExecveMagic); int saved_errno = errno; SAPI_RAW_PLOG(ERROR, "sandbox2::ForkServer: execveat failed"); diff --git a/sandboxed_api/sandbox2/global_forkclient.cc b/sandboxed_api/sandbox2/global_forkclient.cc index 3089233..25d5405 100644 --- a/sandboxed_api/sandbox2/global_forkclient.cc +++ b/sandboxed_api/sandbox2/global_forkclient.cc @@ -49,6 +49,7 @@ #include "sandboxed_api/sandbox2/comms.h" #include "sandboxed_api/sandbox2/fork_client.h" #include "sandboxed_api/sandbox2/forkserver_bin_embed.h" +#include "sandboxed_api/sandbox2/util.h" #include "sandboxed_api/util/fileops.h" #include "sandboxed_api/util/raw_logging.h" @@ -142,11 +143,8 @@ int LaunchForkserver(void* vargs) { char proc_name[] = "S2-FORK-SERV"; char* const argv[] = {proc_name, nullptr}; - char* const envp[] = {nullptr}; - - syscall(__NR_execveat, args->exec_fd, "", argv, envp, AT_EMPTY_PATH); + util::Execveat(args->exec_fd, "", argv, environ, AT_EMPTY_PATH); SAPI_RAW_PLOG(FATAL, "Could not launch forkserver binary"); - abort(); } absl::StatusOr> StartGlobalForkServer() { diff --git a/sandboxed_api/sandbox2/util.cc b/sandboxed_api/sandbox2/util.cc index fb1d90c..584566c 100644 --- a/sandboxed_api/sandbox2/util.cc +++ b/sandboxed_api/sandbox2/util.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include "absl/algorithm/container.h" #include "absl/base/attributes.h" @@ -68,6 +69,32 @@ std::string ConcatenateAll(char* const* arr) { return result; } +#ifdef __ELF__ +extern "C" void __gcov_dump() ABSL_ATTRIBUTE_WEAK; +extern "C" void __gcov_flush() ABSL_ATTRIBUTE_WEAK; +extern "C" void __gcov_reset() ABSL_ATTRIBUTE_WEAK; +#endif + +void DumpCoverageData() { +#ifdef __ELF__ + if (&__gcov_dump != nullptr) { + SAPI_RAW_LOG(WARNING, "Flushing coverage data (dump)"); + __gcov_dump(); + } else if (&__gcov_flush != nullptr) { + SAPI_RAW_LOG(WARNING, "Flushing coverage data (flush)"); + __gcov_flush(); + } +#endif +} + +void ResetCoverageData() { +#ifdef __ELF__ + if (&__gcov_reset != nullptr) { + __gcov_reset(); + } +#endif +} + } // namespace void CharPtrArrToVecString(char* const* arr, std::vector* vec) { @@ -400,4 +427,22 @@ absl::StatusOr ReadCPathFromPid(pid_t pid, uintptr_t ptr) { return path; } +int Execveat(int dirfd, const char* pathname, const char* const argv[], + const char* const envp[], int flags, uintptr_t extra_arg) { + // Flush coverage data prior to exec. + if (extra_arg == 0) { + DumpCoverageData(); + } + int res = syscall(__NR_execveat, static_cast(dirfd), + reinterpret_cast(pathname), + reinterpret_cast(argv), + reinterpret_cast(envp), + static_cast(flags), extra_arg); + // Reset coverage data if exec fails as the counters have been already dumped. + if (extra_arg == 0) { + ResetCoverageData(); + } + return res; +} + } // namespace sandbox2::util diff --git a/sandboxed_api/sandbox2/util.h b/sandboxed_api/sandbox2/util.h index f91aa01..72516dc 100644 --- a/sandboxed_api/sandbox2/util.h +++ b/sandboxed_api/sandbox2/util.h @@ -106,6 +106,10 @@ std::string GetPtraceEventName(int event); // process memory absl::StatusOr ReadCPathFromPid(pid_t pid, uintptr_t ptr); +// Wrapper for execveat(2). +int Execveat(int dirfd, const char* pathname, const char* const argv[], + const char* const envp[], int flags, uintptr_t extra_arg = 0); + } // namespace sandbox2::util #endif // SANDBOXED_API_SANDBOX2_UTIL_H_