diff --git a/sandboxed_api/sandbox2/BUILD.bazel b/sandboxed_api/sandbox2/BUILD.bazel index 60ff718..aa40229 100644 --- a/sandboxed_api/sandbox2/BUILD.bazel +++ b/sandboxed_api/sandbox2/BUILD.bazel @@ -371,6 +371,7 @@ cc_library( copts = sapi_platform_copts(), visibility = ["//visibility:public"], deps = [ + ":util", "//sandboxed_api/util:file_helpers", "//sandboxed_api/util:fileops", "//sandboxed_api/util:raw_logging", @@ -537,6 +538,7 @@ cc_library( deps = [ "//sandboxed_api:config", "//sandboxed_api/util:file_base", + "//sandboxed_api/util:file_helpers", "//sandboxed_api/util:fileops", "//sandboxed_api/util:raw_logging", "//sandboxed_api/util:strerror", diff --git a/sandboxed_api/sandbox2/CMakeLists.txt b/sandboxed_api/sandbox2/CMakeLists.txt index d5544c1..14c9c80 100644 --- a/sandboxed_api/sandbox2/CMakeLists.txt +++ b/sandboxed_api/sandbox2/CMakeLists.txt @@ -492,6 +492,7 @@ target_link_libraries(sandbox2_util absl::strings sapi::config sapi::file_base + sapi::file_helpers sapi::fileops sapi::strerror sapi::base diff --git a/sandboxed_api/sandbox2/monitor.cc b/sandboxed_api/sandbox2/monitor.cc index d3e69b6..db78134 100644 --- a/sandboxed_api/sandbox2/monitor.cc +++ b/sandboxed_api/sandbox2/monitor.cc @@ -756,6 +756,11 @@ void Monitor::LogSyscallViolation(const Syscall& syscall) const { LOG(ERROR) << "SANDBOX VIOLATION : PID: " << syscall.pid() << ", PROG: '" << util::GetProgName(syscall.pid()) << "' : " << syscall.GetDescription(); + if (VLOG_IS_ON(1)) { + VLOG(1) << "Cmdline: " << util::GetCmdLine(syscall.pid()); + VLOG(1) << "Task Name: " << util::GetProcStatusLine(syscall.pid(), "Name"); + VLOG(1) << "Tgid: " << util::GetProcStatusLine(syscall.pid(), "Tgid"); + } LogSyscallViolationExplanation(syscall); } diff --git a/sandboxed_api/sandbox2/sanitizer.cc b/sandboxed_api/sandbox2/sanitizer.cc index e22ddee..4c19d75 100644 --- a/sandboxed_api/sandbox2/sanitizer.cc +++ b/sandboxed_api/sandbox2/sanitizer.cc @@ -38,6 +38,7 @@ #include "absl/strings/numbers.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_split.h" +#include "sandboxed_api/sandbox2/util.h" #include "sandboxed_api/util/file_helpers.h" #include "sandboxed_api/util/fileops.h" #include "sandboxed_api/util/raw_logging.h" @@ -73,30 +74,6 @@ bool ListNumericalDirectoryEntries(const std::string& directory, return true; } -// Returns the specified line from /proc//status. -std::string GetProcStatusLine(int pid, const std::string& value) { - const std::string fname = absl::StrCat("/proc/", pid, "/status"); - std::string procpidstatus; - auto status = file::GetContents(fname, &procpidstatus, file::Defaults()); - if (!status.ok()) { - SAPI_RAW_LOG(WARNING, "%s", std::string(status.message()).c_str()); - return ""; - } - - for (const auto& line : absl::StrSplit(procpidstatus, '\n')) { - std::pair kv = - absl::StrSplit(line, absl::MaxSplits(':', 1)); - SAPI_RAW_VLOG(3, "Key: '%s' Value: '%s'", kv.first.c_str(), - kv.second.c_str()); - if (kv.first == value) { - return std::move(kv.second); - } - } - SAPI_RAW_LOG(ERROR, "No '%s' field found in '%s'", value.c_str(), - fname.c_str()); - return ""; -} - } // namespace bool GetListOfFDs(std::set* fds) { @@ -164,7 +141,7 @@ bool MarkAllFDsAsCOEExcept(const std::set& fd_exceptions) { } int GetNumberOfThreads(int pid) { - std::string thread_str = GetProcStatusLine(pid, "Threads"); + std::string thread_str = util::GetProcStatusLine(pid, "Threads"); if (thread_str.empty()) { return -1; } diff --git a/sandboxed_api/sandbox2/util.cc b/sandboxed_api/sandbox2/util.cc index 8670700..786165e 100644 --- a/sandboxed_api/sandbox2/util.cc +++ b/sandboxed_api/sandbox2/util.cc @@ -35,13 +35,17 @@ #include "absl/base/attributes.h" #include "absl/status/statusor.h" +#include "absl/strings/ascii.h" #include "absl/strings/escaping.h" #include "absl/strings/numbers.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" +#include "absl/strings/str_replace.h" +#include "absl/strings/str_split.h" #include "absl/strings/string_view.h" #include "absl/strings/strip.h" #include "sandboxed_api/config.h" +#include "sandboxed_api/util/file_helpers.h" #include "sandboxed_api/util/fileops.h" #include "sandboxed_api/util/path.h" #include "sandboxed_api/util/raw_logging.h" @@ -77,6 +81,43 @@ std::string GetProgName(pid_t pid) { return file_util::fileops::Basename(file_util::fileops::ReadLink(fname)); } +std::string GetCmdLine(pid_t pid) { + std::string fname = file::JoinPath("/proc", absl::StrCat(pid), "cmdline"); + std::string cmdline; + auto status = + sapi::file::GetContents(fname, &cmdline, sapi::file::Defaults()); + if (!status.ok()) { + SAPI_RAW_LOG(WARNING, "%s", std::string(status.message()).c_str()); + return ""; + } + return absl::StrReplaceAll(cmdline, {{absl::string_view("\0", 1), " "}}); +} + +std::string GetProcStatusLine(int pid, const std::string& value) { + const std::string fname = absl::StrCat("/proc/", pid, "/status"); + std::string procpidstatus; + auto status = + sapi::file::GetContents(fname, &procpidstatus, sapi::file::Defaults()); + if (!status.ok()) { + SAPI_RAW_LOG(WARNING, "%s", std::string(status.message()).c_str()); + return ""; + } + + for (const auto& line : absl::StrSplit(procpidstatus, '\n')) { + std::pair kv = + absl::StrSplit(line, absl::MaxSplits(':', 1)); + SAPI_RAW_VLOG(3, "Key: '%s' Value: '%s'", kv.first.c_str(), + kv.second.c_str()); + if (kv.first == value) { + absl::StripLeadingAsciiWhitespace(&kv.second); + return std::move(kv.second); + } + } + SAPI_RAW_LOG(ERROR, "No '%s' field found in '%s'", value.c_str(), + fname.c_str()); + return ""; +} + long Syscall(long sys_no, // NOLINT uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6) { diff --git a/sandboxed_api/sandbox2/util.h b/sandboxed_api/sandbox2/util.h index 95f52cc..b09771c 100644 --- a/sandboxed_api/sandbox2/util.h +++ b/sandboxed_api/sandbox2/util.h @@ -41,6 +41,14 @@ const char** VecStringToCharPtrArr(const std::vector& vec); // Returns the program name (via /proc/self/comm) for a given PID. std::string GetProgName(pid_t pid); +// Returns the command line (via /proc/self/cmdline) for a given PID. The +// argument separators '\0' are converted to spaces. +std::string GetCmdLine(pid_t pid); + +// Returns the specified line from /proc//status for a given PID. 'value' +// is a field name like "Threads" or "Tgid". +std::string GetProcStatusLine(int pid, const std::string& value); + // Invokes a syscall, avoiding on-stack argument promotion, as it might happen // with vararg syscall() function. long Syscall(long sys_no, // NOLINT