diff options
author | Oliver Chang <oliverchang@users.noreply.github.com> | 2022-06-29 12:05:17 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-29 02:05:17 +0000 |
commit | a2eaeebecb37139041fcbb7a4e605567778634d5 (patch) | |
tree | e8a19916f21e31f7444dee9235005a74a8789b85 | |
parent | d24a351bc8e0131263a0ec0cc9701214c966bf82 (diff) |
execSan: Return same exit status as the child. (#7924)
* execSan: Return same exit status as the child.
* format
-rw-r--r-- | infra/experimental/sanitizers/ExecSan/execSan.cpp | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/infra/experimental/sanitizers/ExecSan/execSan.cpp b/infra/experimental/sanitizers/ExecSan/execSan.cpp index b1c6f335..15c1cc1b 100644 --- a/infra/experimental/sanitizers/ExecSan/execSan.cpp +++ b/infra/experimental/sanitizers/ExecSan/execSan.cpp @@ -267,7 +267,8 @@ void inspect_for_corruption(pid_t pid, const user_regs_struct ®s) { match_error_pattern(buffer, g_shell_pids[pid]); } -void trace(std::map<pid_t, Tracee> pids) { +int trace(std::map<pid_t, Tracee> pids) { + unsigned long exit_status = 0; while (!pids.empty()) { std::vector<pid_t> new_pids; @@ -315,6 +316,21 @@ void trace(std::map<pid_t, Tracee> pids) { debug_log("forwarding signal %d to %d", sig, pid); } + if ((status >> 8 == (SIGTRAP | (PTRACE_EVENT_EXIT << 8)))) { + debug_log("%d exiting", pid); + if (pid == g_root_pid) { + if (ptrace(PTRACE_GETEVENTMSG, pid, 0, &exit_status) == -1) { + debug_log("ptrace(PTRACE_GETEVENTMSG, %d): %s", pid, strerror(errno)); + } + debug_log("got exit status from root process: %lu", exit_status); + } + + if (ptrace(PTRACE_DETACH, pid, 0, 0) == -1) { + debug_log("ptrace(PTRACE_DETACH, %d): %s", pid, strerror(errno)); + } + continue; + } + if (WIFSTOPPED(status) && (status >> 8 == (SIGTRAP | (PTRACE_EVENT_CLONE << 8)) || status >> 8 == (SIGTRAP | (PTRACE_EVENT_FORK << 8)) || @@ -374,6 +390,7 @@ void trace(std::map<pid_t, Tracee> pids) { pids.emplace(pid, Tracee(pid)); } } + return static_cast<int>(exit_status >> 8); } int main(int argc, char **argv) { @@ -390,7 +407,8 @@ int main(int argc, char **argv) { pid_t pid = run_child(argv + 1); long options = PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEFORK | - PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE; + PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE | + PTRACE_O_TRACEEXIT; if (ptrace(PTRACE_SEIZE, pid, nullptr, options) == -1) { fatal_log("ptrace(PTRACE_SEIZE): %s", strerror(errno)); @@ -407,5 +425,5 @@ int main(int argc, char **argv) { g_root_pid = pid; std::map<pid_t, Tracee> pids; pids.emplace(pid, Tracee(pid)); - trace(pids); + return trace(pids); } |