From 654668fc4e3fe3270fd9087919ee32d38e300633 Mon Sep 17 00:00:00 2001 From: Wiktor Garbacz Date: Mon, 12 Jun 2023 00:14:06 -0700 Subject: [PATCH] stack_trace: avoid copying /proc/{pid}/exe if possible The executable might not be inside the mount tree. PiperOrigin-RevId: 539564862 Change-Id: I94e748608a36c8e9203ffe4b6de443e026e4546a --- sandboxed_api/sandbox2/stack_trace.cc | 29 ++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/sandboxed_api/sandbox2/stack_trace.cc b/sandboxed_api/sandbox2/stack_trace.cc index 1c685a8..36523e1 100644 --- a/sandboxed_api/sandbox2/stack_trace.cc +++ b/sandboxed_api/sandbox2/stack_trace.cc @@ -18,9 +18,11 @@ #include #include +#include #include #include +#include #include #include @@ -65,6 +67,20 @@ absl::StatusOr> UnsafeGetStackTrace(pid_t pid) { return RunLibUnwindAndSymbolizer(pid, kDefaultMaxFrames); } +bool IsSameFile(const std::string& path, const std::string& other) { + struct stat buf, other_buf; + if (stat(path.c_str(), &buf) != 0 || stat(other.c_str(), &other_buf) != 0) { + return false; + } + return buf.st_dev == other_buf.st_dev && buf.st_ino == other_buf.st_ino && + buf.st_mode == other_buf.st_mode && + buf.st_nlink == other_buf.st_nlink && buf.st_uid == other_buf.st_uid && + buf.st_gid == other_buf.st_gid && buf.st_rdev == other_buf.st_rdev && + buf.st_size == other_buf.st_size && + buf.st_blksize == other_buf.st_blksize && + buf.st_blocks == other_buf.st_blocks; +} + } // namespace class StackTracePeer { @@ -211,11 +227,14 @@ absl::StatusOr> StackTracePeer::LaunchLibunwindSandbox( return absl::InternalError("Could not obtain absolute path to the binary"); } - // The exe_path will have a mountable path of the application, even if it was - // removed. - // Resolve app_path backing file. - std::string exe_path = - ns ? ns->mounts().ResolvePath(app_path).value_or("") : ""; + std::string exe_path; + if (IsSameFile(app_path, proc_pid_exe)) { + exe_path = app_path; + } else { + // The exe_path will have a mountable path of the application, even if it + // was removed. Resolve app_path backing file. + exe_path = ns ? ns->mounts().ResolvePath(app_path).value_or("") : ""; + } if (exe_path.empty()) { // File was probably removed.