gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/ptrace.cc (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  #include <elf.h>
    16  #include <signal.h>
    17  #include <stddef.h>
    18  #include <sys/prctl.h>
    19  #include <sys/ptrace.h>
    20  #include <sys/socket.h>
    21  #include <sys/time.h>
    22  #include <sys/types.h>
    23  #include <sys/user.h>
    24  #include <sys/wait.h>
    25  #include <unistd.h>
    26  
    27  #include <iostream>
    28  #include <utility>
    29  
    30  #include "gmock/gmock.h"
    31  #include "gtest/gtest.h"
    32  #include "absl/flags/flag.h"
    33  #include "absl/strings/string_view.h"
    34  #include "absl/time/clock.h"
    35  #include "absl/time/time.h"
    36  #include "test/util/capability_util.h"
    37  #include "test/util/fs_util.h"
    38  #include "test/util/logging.h"
    39  #include "test/util/memory_util.h"
    40  #include "test/util/multiprocess_util.h"
    41  #include "test/util/platform_util.h"
    42  #include "test/util/signal_util.h"
    43  #include "test/util/temp_path.h"
    44  #include "test/util/test_util.h"
    45  #include "test/util/thread_util.h"
    46  #include "test/util/time_util.h"
    47  
    48  ABSL_FLAG(bool, ptrace_test_execve_child, false,
    49            "If true, run the "
    50            "PtraceExecveTest_Execve_GetRegs_PeekUser_SIGKILL_TraceClone_"
    51            "TraceExit child workload.");
    52  ABSL_FLAG(bool, ptrace_test_trace_descendants_allowed, false,
    53            "If set, run the child workload for "
    54            "PtraceTest_TraceDescendantsAllowed.");
    55  ABSL_FLAG(bool, ptrace_test_ptrace_attacher, false,
    56            "If set, run the child workload for PtraceAttacherSubprocess.");
    57  ABSL_FLAG(bool, ptrace_test_prctl_set_ptracer, false,
    58            "If set, run the child workload for PrctlSetPtracerSubprocess.");
    59  ABSL_FLAG(bool, ptrace_test_prctl_set_ptracer_and_exit_tracee_thread, false,
    60            "If set, run the child workload for "
    61            "PtraceTest_PrctlSetPtracerPersistsPastTraceeThreadExit.");
    62  ABSL_FLAG(bool, ptrace_test_prctl_set_ptracer_and_exec_non_leader, false,
    63            "If set, run the child workload for "
    64            "PtraceTest_PrctlSetPtracerDoesNotPersistPastNonLeaderExec.");
    65  ABSL_FLAG(bool, ptrace_test_prctl_set_ptracer_and_exit_tracer_thread, false,
    66            "If set, run the child workload for "
    67            "PtraceTest_PrctlSetPtracerDoesNotPersistPastTracerThreadExit.");
    68  ABSL_FLAG(int, ptrace_test_prctl_set_ptracer_and_exit_tracer_thread_tid, -1,
    69            "Specifies the tracee tid in the child workload for "
    70            "PtraceTest_PrctlSetPtracerDoesNotPersistPastTracerThreadExit.");
    71  ABSL_FLAG(bool, ptrace_test_prctl_set_ptracer_respects_tracer_thread_id, false,
    72            "If set, run the child workload for PtraceTest_PrctlSetPtracePID.");
    73  ABSL_FLAG(int, ptrace_test_prctl_set_ptracer_respects_tracer_thread_id_tid, -1,
    74            "Specifies the thread tid to be traced in the child workload "
    75            "for PtraceTest_PrctlSetPtracerRespectsTracerThreadID.");
    76  
    77  ABSL_FLAG(bool, ptrace_test_tracee, false,
    78            "If true, run the tracee process for the "
    79            "PrctlSetPtracerDoesNotPersistPastLeaderExec and "
    80            "PrctlSetPtracerDoesNotPersistPastNonLeaderExec workloads.");
    81  ABSL_FLAG(int, ptrace_test_trace_tid, -1,
    82            "If set, run a process to ptrace attach to the thread with the "
    83            "specified pid for the PrctlSetPtracerRespectsTracerThreadID "
    84            "workload.");
    85  ABSL_FLAG(int, ptrace_test_fd, -1,
    86            "Specifies the fd used for communication between tracer and tracee "
    87            "processes across exec.");
    88  
    89  namespace gvisor {
    90  namespace testing {
    91  
    92  namespace {
    93  
    94  // PTRACE_GETSIGMASK and PTRACE_SETSIGMASK are not defined until glibc 2.23
    95  // (fb53a27c5741 "Add new header definitions from Linux 4.4 (plus older ptrace
    96  // definitions)").
    97  constexpr auto kPtraceGetSigMask = static_cast<__ptrace_request>(0x420a);
    98  constexpr auto kPtraceSetSigMask = static_cast<__ptrace_request>(0x420b);
    99  
   100  // PTRACE_SYSEMU is not defined until glibc 2.27 (c48831d0eebf "linux/x86: sync
   101  // sys/ptrace.h with Linux 4.14 [BZ #22433]").
   102  constexpr auto kPtraceSysemu = static_cast<__ptrace_request>(31);
   103  
   104  // PTRACE_EVENT_STOP is not defined until glibc 2.26 (3f67d1a7021e "Add Linux
   105  // PTRACE_EVENT_STOP").
   106  constexpr int kPtraceEventStop = 128;
   107  
   108  // Sends sig to the current process with tgkill(2).
   109  //
   110  // glibc's raise(2) may change the signal mask before sending the signal. These
   111  // extra syscalls make tests of syscall, signal interception, etc. difficult to
   112  // write.
   113  void RaiseSignal(int sig) {
   114    pid_t pid = getpid();
   115    TEST_PCHECK(pid > 0);
   116    pid_t tid = gettid();
   117    TEST_PCHECK(tid > 0);
   118    TEST_PCHECK(tgkill(pid, tid, sig) == 0);
   119  }
   120  
   121  constexpr char kYamaPtraceScopePath[] = "/proc/sys/kernel/yama/ptrace_scope";
   122  
   123  // Returns the Yama ptrace scope.
   124  PosixErrorOr<int> YamaPtraceScope() {
   125    ASSIGN_OR_RETURN_ERRNO(bool exists, Exists(kYamaPtraceScopePath));
   126    if (!exists) {
   127      // File doesn't exist means no Yama, so the scope is disabled -> 0.
   128      return 0;
   129    }
   130  
   131    std::string contents;
   132    RETURN_IF_ERRNO(GetContents(kYamaPtraceScopePath, &contents));
   133  
   134    int scope;
   135    if (!absl::SimpleAtoi(contents, &scope)) {
   136      return PosixError(EINVAL, absl::StrCat(contents, ": not a valid number"));
   137    }
   138  
   139    return scope;
   140  }
   141  
   142  int CheckPtraceAttach(pid_t pid) {
   143    int ret = ptrace(PTRACE_ATTACH, pid, 0, 0);
   144    MaybeSave();
   145    if (ret < 0) {
   146      return ret;
   147    }
   148  
   149    int status;
   150    TEST_PCHECK(waitpid(pid, &status, 0) == pid);
   151    MaybeSave();
   152    TEST_CHECK(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP);
   153    TEST_PCHECK(ptrace(PTRACE_DETACH, pid, 0, 0) == 0);
   154    MaybeSave();
   155    return 0;
   156  }
   157  
   158  class SimpleSubprocess {
   159   public:
   160    explicit SimpleSubprocess(absl::string_view child_flag) {
   161      int sockets[2];
   162      TEST_PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == 0);
   163  
   164      // Allocate vector before forking (not async-signal-safe).
   165      ExecveArray const owned_child_argv = {"/proc/self/exe", child_flag,
   166                                            "--ptrace_test_fd",
   167                                            std::to_string(sockets[0])};
   168      char* const* const child_argv = owned_child_argv.get();
   169  
   170      pid_ = fork();
   171      if (pid_ == 0) {
   172        TEST_PCHECK(close(sockets[1]) == 0);
   173        execve(child_argv[0], child_argv, /* envp = */ nullptr);
   174        TEST_PCHECK_MSG(false, "Survived execve to test child");
   175      }
   176      TEST_PCHECK(pid_ > 0);
   177      TEST_PCHECK(close(sockets[0]) == 0);
   178      sockfd_ = sockets[1];
   179    }
   180  
   181    SimpleSubprocess(SimpleSubprocess&& orig)
   182        : pid_(orig.pid_), sockfd_(orig.sockfd_) {
   183      orig.pid_ = -1;
   184      orig.sockfd_ = -1;
   185    }
   186  
   187    SimpleSubprocess& operator=(SimpleSubprocess&& orig) {
   188      if (this != &orig) {
   189        this->~SimpleSubprocess();
   190        pid_ = orig.pid_;
   191        sockfd_ = orig.sockfd_;
   192        orig.pid_ = -1;
   193        orig.sockfd_ = -1;
   194      }
   195      return *this;
   196    }
   197  
   198    SimpleSubprocess(SimpleSubprocess const&) = delete;
   199    SimpleSubprocess& operator=(SimpleSubprocess const&) = delete;
   200  
   201    ~SimpleSubprocess() {
   202      if (pid_ < 0) {
   203        return;
   204      }
   205      EXPECT_THAT(shutdown(sockfd_, SHUT_RDWR), SyscallSucceeds());
   206      EXPECT_THAT(close(sockfd_), SyscallSucceeds());
   207      int status;
   208      EXPECT_THAT(waitpid(pid_, &status, 0), SyscallSucceedsWithValue(pid_));
   209      EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   210          << " status " << status;
   211    }
   212  
   213    pid_t pid() const { return pid_; }
   214  
   215    // Sends the child process the given value, receives an errno in response, and
   216    // returns a PosixError corresponding to the received errno.
   217    template <typename T>
   218    PosixError Cmd(T val) {
   219      if (WriteFd(sockfd_, &val, sizeof(val)) < 0) {
   220        return PosixError(errno, "write failed");
   221      }
   222      return RecvErrno();
   223    }
   224  
   225   private:
   226    PosixError RecvErrno() {
   227      int resp_errno;
   228      if (ReadFd(sockfd_, &resp_errno, sizeof(resp_errno)) < 0) {
   229        return PosixError(errno, "read failed");
   230      }
   231      return PosixError(resp_errno);
   232    }
   233  
   234    pid_t pid_ = -1;
   235    int sockfd_ = -1;
   236  };
   237  
   238  TEST(PtraceTest, AttachSelf) {
   239    EXPECT_THAT(ptrace(PTRACE_ATTACH, gettid(), 0, 0),
   240                SyscallFailsWithErrno(EPERM));
   241  }
   242  
   243  TEST(PtraceTest, AttachSameThreadGroup) {
   244    pid_t const tid = gettid();
   245    ScopedThread([&] {
   246      EXPECT_THAT(ptrace(PTRACE_ATTACH, tid, 0, 0), SyscallFailsWithErrno(EPERM));
   247    });
   248  }
   249  
   250  TEST(PtraceTest, TraceParentNotAllowed) {
   251    SKIP_IF(ASSERT_NO_ERRNO_AND_VALUE(YamaPtraceScope()) < 1);
   252    AutoCapability cap(CAP_SYS_PTRACE, false);
   253  
   254    pid_t const child_pid = fork();
   255    if (child_pid == 0) {
   256      TEST_CHECK(CheckPtraceAttach(getppid()) == -1);
   257      TEST_PCHECK(errno == EPERM);
   258      _exit(0);
   259    }
   260    ASSERT_THAT(child_pid, SyscallSucceeds());
   261  
   262    int status;
   263    ASSERT_THAT(waitpid(child_pid, &status, 0), SyscallSucceeds());
   264    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   265        << " status " << status;
   266  }
   267  
   268  TEST(PtraceTest, TraceNonDescendantNotAllowed) {
   269    SKIP_IF(ASSERT_NO_ERRNO_AND_VALUE(YamaPtraceScope()) < 1);
   270    AutoCapability cap(CAP_SYS_PTRACE, false);
   271  
   272    pid_t const tracee_pid = fork();
   273    if (tracee_pid == 0) {
   274      while (true) {
   275        SleepSafe(absl::Seconds(1));
   276      }
   277    }
   278    ASSERT_THAT(tracee_pid, SyscallSucceeds());
   279  
   280    pid_t const tracer_pid = fork();
   281    if (tracer_pid == 0) {
   282      TEST_CHECK(CheckPtraceAttach(tracee_pid) == -1);
   283      TEST_PCHECK(errno == EPERM);
   284      _exit(0);
   285    }
   286    EXPECT_THAT(tracer_pid, SyscallSucceeds());
   287  
   288    // Clean up tracer.
   289    int status;
   290    ASSERT_THAT(waitpid(tracer_pid, &status, 0), SyscallSucceeds());
   291    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
   292  
   293    // Clean up tracee.
   294    ASSERT_THAT(kill(tracee_pid, SIGKILL), SyscallSucceeds());
   295    ASSERT_THAT(waitpid(tracee_pid, &status, 0),
   296                SyscallSucceedsWithValue(tracee_pid));
   297    EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
   298        << " status " << status;
   299  }
   300  
   301  TEST(PtraceTest, TraceNonDescendantWithCapabilityAllowed) {
   302    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_PTRACE)));
   303    // Skip if disallowed by YAMA despite having CAP_SYS_PTRACE.
   304    SKIP_IF(ASSERT_NO_ERRNO_AND_VALUE(YamaPtraceScope()) > 2);
   305  
   306    pid_t const tracee_pid = fork();
   307    if (tracee_pid == 0) {
   308      while (true) {
   309        SleepSafe(absl::Seconds(1));
   310      }
   311    }
   312    ASSERT_THAT(tracee_pid, SyscallSucceeds());
   313  
   314    pid_t const tracer_pid = fork();
   315    if (tracer_pid == 0) {
   316      TEST_PCHECK(CheckPtraceAttach(tracee_pid) == 0);
   317      _exit(0);
   318    }
   319    ASSERT_THAT(tracer_pid, SyscallSucceeds());
   320  
   321    // Clean up tracer.
   322    int status;
   323    ASSERT_THAT(waitpid(tracer_pid, &status, 0), SyscallSucceeds());
   324    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
   325  
   326    // Clean up tracee.
   327    ASSERT_THAT(kill(tracee_pid, SIGKILL), SyscallSucceeds());
   328    ASSERT_THAT(waitpid(tracee_pid, &status, 0),
   329                SyscallSucceedsWithValue(tracee_pid));
   330    EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
   331        << " status " << status;
   332  }
   333  
   334  TEST(PtraceTest, TraceDescendantsAllowed) {
   335    SKIP_IF(ASSERT_NO_ERRNO_AND_VALUE(YamaPtraceScope()) > 1);
   336    AutoCapability cap(CAP_SYS_PTRACE, false);
   337  
   338    // Use socket pair to communicate tids to this process from its grandchild.
   339    int sockets[2];
   340    ASSERT_THAT(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets), SyscallSucceeds());
   341  
   342    // Allocate vector before forking (not async-signal-safe).
   343    ExecveArray const owned_child_argv = {
   344        "/proc/self/exe", "--ptrace_test_trace_descendants_allowed",
   345        "--ptrace_test_fd", std::to_string(sockets[0])};
   346    char* const* const child_argv = owned_child_argv.get();
   347  
   348    pid_t const child_pid = fork();
   349    if (child_pid == 0) {
   350      // In child process.
   351      TEST_PCHECK(close(sockets[1]) == 0);
   352      pid_t const grandchild_pid = fork();
   353      if (grandchild_pid == 0) {
   354        // This test will create a new thread in the grandchild process.
   355        // pthread_create(2) isn't async-signal-safe, so we execve() first.
   356        execve(child_argv[0], child_argv, /* envp = */ nullptr);
   357        TEST_PCHECK_MSG(false, "Survived execve to test child");
   358      }
   359      TEST_PCHECK(grandchild_pid > 0);
   360      MaybeSave();
   361  
   362      // Wait for grandchild. Our parent process will kill it once it's done.
   363      int status;
   364      TEST_PCHECK(waitpid(grandchild_pid, &status, 0) == grandchild_pid);
   365      TEST_CHECK(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL);
   366      MaybeSave();
   367      _exit(0);
   368    }
   369    ASSERT_THAT(child_pid, SyscallSucceeds());
   370    ASSERT_THAT(close(sockets[0]), SyscallSucceeds());
   371  
   372    // We should be able to attach to any thread in the grandchild.
   373    pid_t grandchild_tid1, grandchild_tid2;
   374    ASSERT_THAT(read(sockets[1], &grandchild_tid1, sizeof(grandchild_tid1)),
   375                SyscallSucceedsWithValue(sizeof(grandchild_tid1)));
   376    ASSERT_THAT(read(sockets[1], &grandchild_tid2, sizeof(grandchild_tid2)),
   377                SyscallSucceedsWithValue(sizeof(grandchild_tid2)));
   378  
   379    EXPECT_THAT(CheckPtraceAttach(grandchild_tid1), SyscallSucceeds());
   380    EXPECT_THAT(CheckPtraceAttach(grandchild_tid2), SyscallSucceeds());
   381  
   382    // Clean up grandchild.
   383    ASSERT_THAT(kill(grandchild_tid1, SIGKILL), SyscallSucceeds());
   384  
   385    // Clean up child.
   386    int status;
   387    ASSERT_THAT(waitpid(child_pid, &status, 0),
   388                SyscallSucceedsWithValue(child_pid));
   389    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   390        << " status " << status;
   391  }
   392  
   393  [[noreturn]] void RunTraceDescendantsAllowed(int fd) {
   394    // Let the tracer know our tid through the socket fd.
   395    pid_t const tid = gettid();
   396    TEST_PCHECK(write(fd, &tid, sizeof(tid)) == sizeof(tid));
   397    MaybeSave();
   398  
   399    ScopedThread t([fd] {
   400      // See if any arbitrary thread (whose tid differs from the process id) can
   401      // be traced as well.
   402      pid_t const tid = gettid();
   403      TEST_PCHECK(write(fd, &tid, sizeof(tid)) == sizeof(tid));
   404      MaybeSave();
   405      while (true) {
   406        SleepSafe(absl::Seconds(1));
   407      }
   408    });
   409  
   410    while (true) {
   411      SleepSafe(absl::Seconds(1));
   412    }
   413  }
   414  
   415  TEST(PtraceTest, PrctlSetPtracerInvalidPID) {
   416    // EINVAL should also be returned if PR_SET_PTRACER is not supported.
   417    EXPECT_THAT(prctl(PR_SET_PTRACER, 123456789), SyscallFailsWithErrno(EINVAL));
   418  }
   419  
   420  SimpleSubprocess CreatePtraceAttacherSubprocess() {
   421    return SimpleSubprocess("--ptrace_test_ptrace_attacher");
   422  }
   423  
   424  [[noreturn]] static void RunPtraceAttacher(int sockfd) {
   425    // execve() may have restored CAP_SYS_PTRACE if we had real UID 0.
   426    TEST_CHECK(SetCapability(CAP_SYS_PTRACE, false).ok());
   427    // Perform PTRACE_ATTACH in a separate thread to verify that permissions
   428    // apply process-wide.
   429    ScopedThread t([&] {
   430      while (true) {
   431        pid_t pid;
   432        int rv = read(sockfd, &pid, sizeof(pid));
   433        if (rv == 0) {
   434          _exit(0);
   435        }
   436        if (rv < 0) {
   437          _exit(1);
   438        }
   439        int resp_errno = 0;
   440        if (CheckPtraceAttach(pid) < 0) {
   441          resp_errno = errno;
   442        }
   443        TEST_PCHECK(write(sockfd, &resp_errno, sizeof(resp_errno)) ==
   444                    sizeof(resp_errno));
   445      }
   446    });
   447    while (true) {
   448      SleepSafe(absl::Seconds(1));
   449    }
   450  }
   451  
   452  SimpleSubprocess CreatePrctlSetPtracerSubprocess() {
   453    return SimpleSubprocess("--ptrace_test_prctl_set_ptracer");
   454  }
   455  
   456  [[noreturn]] static void RunPrctlSetPtracer(int sockfd) {
   457    // Perform prctl in a separate thread to verify that it applies
   458    // process-wide.
   459    ScopedThread t([&] {
   460      while (true) {
   461        pid_t pid;
   462        int rv = read(sockfd, &pid, sizeof(pid));
   463        if (rv == 0) {
   464          _exit(0);
   465        }
   466        if (rv < 0) {
   467          _exit(1);
   468        }
   469        int resp_errno = 0;
   470        if (prctl(PR_SET_PTRACER, pid) < 0) {
   471          resp_errno = errno;
   472        }
   473        TEST_PCHECK(write(sockfd, &resp_errno, sizeof(resp_errno)) ==
   474                    sizeof(resp_errno));
   475      }
   476    });
   477    while (true) {
   478      SleepSafe(absl::Seconds(1));
   479    }
   480  }
   481  
   482  TEST(PtraceTest, PrctlSetPtracer) {
   483    SKIP_IF(ASSERT_NO_ERRNO_AND_VALUE(YamaPtraceScope()) != 1);
   484  
   485    AutoCapability cap(CAP_SYS_PTRACE, false);
   486  
   487    // Ensure that initially, no tracer exception is set.
   488    ASSERT_THAT(prctl(PR_SET_PTRACER, 0), SyscallSucceeds());
   489  
   490    SimpleSubprocess tracee = CreatePrctlSetPtracerSubprocess();
   491    SimpleSubprocess tracer = CreatePtraceAttacherSubprocess();
   492  
   493    // By default, Yama should prevent tracer from tracing its parent (this
   494    // process) or siblings (tracee).
   495    EXPECT_THAT(tracer.Cmd(gettid()), PosixErrorIs(EPERM));
   496    EXPECT_THAT(tracer.Cmd(tracee.pid()), PosixErrorIs(EPERM));
   497  
   498    // If tracee invokes PR_SET_PTRACER on either tracer's pid, the pid of any of
   499    // its ancestors (i.e. us), or PR_SET_PTRACER_ANY, then tracer can trace it
   500    // (but not us).
   501  
   502    ASSERT_THAT(tracee.Cmd(tracer.pid()), PosixErrorIs(0));
   503    EXPECT_THAT(tracer.Cmd(tracee.pid()), PosixErrorIs(0));
   504    EXPECT_THAT(tracer.Cmd(gettid()), PosixErrorIs(EPERM));
   505  
   506    ASSERT_THAT(tracee.Cmd(gettid()), PosixErrorIs(0));
   507    EXPECT_THAT(tracer.Cmd(tracee.pid()), PosixErrorIs(0));
   508    EXPECT_THAT(tracer.Cmd(gettid()), PosixErrorIs(EPERM));
   509  
   510    ASSERT_THAT(tracee.Cmd(static_cast<pid_t>(PR_SET_PTRACER_ANY)),
   511                PosixErrorIs(0));
   512    EXPECT_THAT(tracer.Cmd(tracee.pid()), PosixErrorIs(0));
   513    EXPECT_THAT(tracer.Cmd(gettid()), PosixErrorIs(EPERM));
   514  
   515    // If tracee invokes PR_SET_PTRACER with pid 0, then tracer can no longer
   516    // trace it.
   517    ASSERT_THAT(tracee.Cmd(0), PosixErrorIs(0));
   518    EXPECT_THAT(tracer.Cmd(tracee.pid()), PosixErrorIs(EPERM));
   519  
   520    // If we invoke PR_SET_PTRACER with tracer's pid, then it can trace us (but
   521    // not our descendants).
   522    ASSERT_THAT(prctl(PR_SET_PTRACER, tracer.pid()), SyscallSucceeds());
   523    EXPECT_THAT(tracer.Cmd(gettid()), PosixErrorIs(0));
   524    EXPECT_THAT(tracer.Cmd(tracee.pid()), PosixErrorIs(EPERM));
   525  
   526    // If we invoke PR_SET_PTRACER with pid 0, then tracer can no longer trace us.
   527    ASSERT_THAT(prctl(PR_SET_PTRACER, 0), SyscallSucceeds());
   528    EXPECT_THAT(tracer.Cmd(gettid()), PosixErrorIs(EPERM));
   529  
   530    // Another thread in our thread group can invoke PR_SET_PTRACER instead; its
   531    // effect applies to the whole thread group.
   532    pid_t const our_tid = gettid();
   533    ScopedThread([&] {
   534      ASSERT_THAT(prctl(PR_SET_PTRACER, tracer.pid()), SyscallSucceeds());
   535      EXPECT_THAT(tracer.Cmd(gettid()), PosixErrorIs(0));
   536      EXPECT_THAT(tracer.Cmd(our_tid), PosixErrorIs(0));
   537  
   538      ASSERT_THAT(prctl(PR_SET_PTRACER, 0), SyscallSucceeds());
   539      EXPECT_THAT(tracer.Cmd(gettid()), PosixErrorIs(EPERM));
   540      EXPECT_THAT(tracer.Cmd(our_tid), PosixErrorIs(EPERM));
   541    }).Join();
   542  }
   543  
   544  // Tests that YAMA exceptions store tracees by thread group leader. Exceptions
   545  // are preserved even after the tracee thread exits, as long as the tracee's
   546  // thread group leader is still around.
   547  TEST(PtraceTest, PrctlSetPtracerPersistsPastTraceeThreadExit) {
   548    SKIP_IF(ASSERT_NO_ERRNO_AND_VALUE(YamaPtraceScope()) != 1);
   549    AutoCapability cap(CAP_SYS_PTRACE, false);
   550  
   551    // Use sockets to synchronize between tracer and tracee.
   552    int sockets[2];
   553    ASSERT_THAT(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets), SyscallSucceeds());
   554  
   555    // Allocate vector before forking (not async-signal-safe).
   556    ExecveArray const owned_child_argv = {
   557        "/proc/self/exe",
   558        "--ptrace_test_prctl_set_ptracer_and_exit_tracee_thread",
   559        "--ptrace_test_fd", std::to_string(sockets[0])};
   560    char* const* const child_argv = owned_child_argv.get();
   561  
   562    pid_t const tracee_pid = fork();
   563    if (tracee_pid == 0) {
   564      // This test will create a new thread in the child process.
   565      // pthread_create(2) isn't async-signal-safe, so we execve() first.
   566      TEST_PCHECK(close(sockets[1]) == 0);
   567      execve(child_argv[0], child_argv, /* envp = */ nullptr);
   568      TEST_PCHECK_MSG(false, "Survived execve to test child");
   569    }
   570    ASSERT_THAT(tracee_pid, SyscallSucceeds());
   571    ASSERT_THAT(close(sockets[0]), SyscallSucceeds());
   572  
   573    pid_t const tracer_pid = fork();
   574    if (tracer_pid == 0) {
   575      // Wait until the tracee thread calling prctl has terminated.
   576      char done;
   577      TEST_PCHECK(read(sockets[1], &done, 1) == 1);
   578      MaybeSave();
   579  
   580      TEST_PCHECK(CheckPtraceAttach(tracee_pid) == 0);
   581      _exit(0);
   582    }
   583    ASSERT_THAT(tracer_pid, SyscallSucceeds());
   584  
   585    // Clean up tracer.
   586    int status;
   587    ASSERT_THAT(waitpid(tracer_pid, &status, 0), SyscallSucceeds());
   588    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   589        << " status " << status;
   590  
   591    // Clean up tracee.
   592    ASSERT_THAT(kill(tracee_pid, SIGKILL), SyscallSucceeds());
   593    ASSERT_THAT(waitpid(tracee_pid, &status, 0),
   594                SyscallSucceedsWithValue(tracee_pid));
   595    EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
   596        << " status " << status;
   597  }
   598  
   599  [[noreturn]] void RunPrctlSetPtracerPersistsPastTraceeThreadExit(int fd) {
   600    ScopedThread t([] {
   601      TEST_PCHECK(prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY) == 0);
   602      MaybeSave();
   603    });
   604    t.Join();
   605    // Indicate that thread setting the prctl has exited.
   606    TEST_PCHECK(write(fd, "x", 1) == 1);
   607    MaybeSave();
   608  
   609    while (true) {
   610      SleepSafe(absl::Seconds(1));
   611    }
   612  }
   613  
   614  // Tests that YAMA exceptions store tracees by thread group leader. Exceptions
   615  // are preserved across exec as long as the thread group leader does not change,
   616  // even if the tracee thread is terminated.
   617  TEST(PtraceTest, PrctlSetPtracerPersistsPastLeaderExec) {
   618    SKIP_IF(ASSERT_NO_ERRNO_AND_VALUE(YamaPtraceScope()) != 1);
   619    AutoCapability cap(CAP_SYS_PTRACE, false);
   620  
   621    // Use sockets to synchronize between tracer and tracee.
   622    int sockets[2];
   623    ASSERT_THAT(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets), SyscallSucceeds());
   624  
   625    // Allocate vector before forking (not async-signal-safe).
   626    ExecveArray const owned_child_argv = {
   627        "/proc/self/exe", "--ptrace_test_tracee", "--ptrace_test_fd",
   628        std::to_string(sockets[0])};
   629    char* const* const child_argv = owned_child_argv.get();
   630  
   631    pid_t const tracee_pid = fork();
   632    if (tracee_pid == 0) {
   633      TEST_PCHECK(close(sockets[1]) == 0);
   634      TEST_PCHECK(prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY) == 0);
   635      MaybeSave();
   636  
   637      // This test will create a new thread in the child process.
   638      // pthread_create(2) isn't async-signal-safe, so we execve() first.
   639      execve(child_argv[0], child_argv, /* envp = */ nullptr);
   640      TEST_PCHECK_MSG(false, "Survived execve to test child");
   641    }
   642    ASSERT_THAT(tracee_pid, SyscallSucceeds());
   643    ASSERT_THAT(close(sockets[0]), SyscallSucceeds());
   644  
   645    pid_t const tracer_pid = fork();
   646    if (tracer_pid == 0) {
   647      // Wait until the tracee has exec'd.
   648      char done;
   649      TEST_PCHECK(read(sockets[1], &done, 1) == 1);
   650      MaybeSave();
   651  
   652      TEST_PCHECK(CheckPtraceAttach(tracee_pid) == 0);
   653      _exit(0);
   654    }
   655    ASSERT_THAT(tracer_pid, SyscallSucceeds());
   656  
   657    // Clean up tracer.
   658    int status;
   659    ASSERT_THAT(waitpid(tracer_pid, &status, 0), SyscallSucceeds());
   660    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   661        << " status " << status;
   662  
   663    // Clean up tracee.
   664    ASSERT_THAT(kill(tracee_pid, SIGKILL), SyscallSucceeds());
   665    ASSERT_THAT(waitpid(tracee_pid, &status, 0),
   666                SyscallSucceedsWithValue(tracee_pid));
   667    EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
   668        << " status " << status;
   669  }
   670  
   671  [[noreturn]] void RunTracee(int fd) {
   672    // Indicate that we have exec'd.
   673    TEST_PCHECK(write(fd, "x", 1) == 1);
   674    MaybeSave();
   675  
   676    while (true) {
   677      SleepSafe(absl::Seconds(1));
   678    }
   679  }
   680  
   681  // Tests that YAMA exceptions store tracees by thread group leader. Exceptions
   682  // are cleared if the tracee process's thread group leader is terminated by
   683  // exec.
   684  TEST(PtraceTest, PrctlSetPtracerDoesNotPersistPastNonLeaderExec) {
   685    SKIP_IF(ASSERT_NO_ERRNO_AND_VALUE(YamaPtraceScope()) != 1);
   686    AutoCapability cap(CAP_SYS_PTRACE, false);
   687  
   688    // Use sockets to synchronize between tracer and tracee.
   689    int sockets[2];
   690    ASSERT_THAT(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets), SyscallSucceeds());
   691  
   692    // Allocate vector before forking (not async-signal-safe).
   693    ExecveArray const owned_child_argv = {
   694        "/proc/self/exe", "--ptrace_test_prctl_set_ptracer_and_exec_non_leader",
   695        "--ptrace_test_fd", std::to_string(sockets[0])};
   696    char* const* const child_argv = owned_child_argv.get();
   697  
   698    pid_t const tracee_pid = fork();
   699    if (tracee_pid == 0) {
   700      // This test will create a new thread in the child process.
   701      // pthread_create(2) isn't async-signal-safe, so we execve() first.
   702      TEST_PCHECK(close(sockets[1]) == 0);
   703      execve(child_argv[0], child_argv, /* envp = */ nullptr);
   704      TEST_PCHECK_MSG(false, "Survived execve to test child");
   705    }
   706    ASSERT_THAT(tracee_pid, SyscallSucceeds());
   707    ASSERT_THAT(close(sockets[0]), SyscallSucceeds());
   708  
   709    pid_t const tracer_pid = fork();
   710    if (tracer_pid == 0) {
   711      // Wait until the tracee has exec'd.
   712      char done;
   713      TEST_PCHECK(read(sockets[1], &done, 1) == 1);
   714      MaybeSave();
   715  
   716      TEST_CHECK(CheckPtraceAttach(tracee_pid) == -1);
   717      TEST_PCHECK(errno == EPERM);
   718      _exit(0);
   719    }
   720    ASSERT_THAT(tracer_pid, SyscallSucceeds());
   721  
   722    // Clean up tracer.
   723    int status;
   724    ASSERT_THAT(waitpid(tracer_pid, &status, 0), SyscallSucceeds());
   725    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   726        << " status " << status;
   727  
   728    // Clean up tracee.
   729    ASSERT_THAT(kill(tracee_pid, SIGKILL), SyscallSucceeds());
   730    ASSERT_THAT(waitpid(tracee_pid, &status, 0),
   731                SyscallSucceedsWithValue(tracee_pid));
   732    EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
   733        << " status " << status;
   734  }
   735  
   736  [[noreturn]] void RunPrctlSetPtracerDoesNotPersistPastNonLeaderExec(int fd) {
   737    ScopedThread t([fd] {
   738      TEST_PCHECK(prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY) == 0);
   739      MaybeSave();
   740  
   741      ExecveArray const owned_child_argv = {
   742          "/proc/self/exe", "--ptrace_test_tracee", "--ptrace_test_fd",
   743          std::to_string(fd)};
   744      char* const* const child_argv = owned_child_argv.get();
   745  
   746      execve(child_argv[0], child_argv, /* envp = */ nullptr);
   747      TEST_PCHECK_MSG(false, "Survived execve to test child");
   748    });
   749    t.Join();
   750    TEST_CHECK_MSG(false, "Survived execve? (main)");
   751    _exit(1);
   752  }
   753  
   754  // Tests that YAMA exceptions store the tracer itself rather than the thread
   755  // group leader. Exceptions are cleared when the tracer task exits, rather than
   756  // when its thread group leader exits.
   757  TEST(PtraceTest, PrctlSetPtracerDoesNotPersistPastTracerThreadExit) {
   758    SKIP_IF(ASSERT_NO_ERRNO_AND_VALUE(YamaPtraceScope()) != 1);
   759  
   760    // Use sockets to synchronize between tracer and tracee.
   761    int sockets[2];
   762    ASSERT_THAT(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets), SyscallSucceeds());
   763  
   764    pid_t const tracee_pid = fork();
   765    if (tracee_pid == 0) {
   766      TEST_PCHECK(close(sockets[1]) == 0);
   767      pid_t tracer_tid;
   768      TEST_PCHECK(read(sockets[0], &tracer_tid, sizeof(tracer_tid)) ==
   769                  sizeof(tracer_tid));
   770      MaybeSave();
   771  
   772      TEST_PCHECK(prctl(PR_SET_PTRACER, tracer_tid) == 0);
   773      MaybeSave();
   774      // Indicate that the prctl has been set.
   775      TEST_PCHECK(write(sockets[0], "x", 1) == 1);
   776      MaybeSave();
   777  
   778      while (true) {
   779        SleepSafe(absl::Seconds(1));
   780      }
   781    }
   782    ASSERT_THAT(tracee_pid, SyscallSucceeds());
   783    ASSERT_THAT(close(sockets[0]), SyscallSucceeds());
   784  
   785    // Allocate vector before forking (not async-signal-safe).
   786    ExecveArray const owned_child_argv = {
   787        "/proc/self/exe",
   788        "--ptrace_test_prctl_set_ptracer_and_exit_tracer_thread",
   789        "--ptrace_test_prctl_set_ptracer_and_exit_tracer_thread_tid",
   790        std::to_string(tracee_pid),
   791        "--ptrace_test_fd",
   792        std::to_string(sockets[1])};
   793    char* const* const child_argv = owned_child_argv.get();
   794  
   795    pid_t const tracer_pid = fork();
   796    if (tracer_pid == 0) {
   797      // This test will create a new thread in the child process.
   798      // pthread_create(2) isn't async-signal-safe, so we execve() first.
   799      execve(child_argv[0], child_argv, /* envp = */ nullptr);
   800      TEST_PCHECK_MSG(false, "Survived execve to test child");
   801    }
   802    ASSERT_THAT(tracer_pid, SyscallSucceeds());
   803  
   804    // Clean up tracer.
   805    int status;
   806    ASSERT_THAT(waitpid(tracer_pid, &status, 0), SyscallSucceeds());
   807    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   808        << " status " << status;
   809  
   810    // Clean up tracee.
   811    ASSERT_THAT(kill(tracee_pid, SIGKILL), SyscallSucceeds());
   812    ASSERT_THAT(waitpid(tracee_pid, &status, 0),
   813                SyscallSucceedsWithValue(tracee_pid));
   814    EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
   815        << " status " << status;
   816  }
   817  
   818  [[noreturn]] void RunPrctlSetPtracerDoesNotPersistPastTracerThreadExit(
   819      int tracee_tid, int fd) {
   820    AutoCapability cap(CAP_SYS_PTRACE, false);
   821  
   822    ScopedThread t([fd] {
   823      pid_t const tracer_tid = gettid();
   824      TEST_PCHECK(write(fd, &tracer_tid, sizeof(tracer_tid)) ==
   825                  sizeof(tracer_tid));
   826  
   827      // Wait until the prctl has been set.
   828      char done;
   829      TEST_PCHECK(read(fd, &done, 1) == 1);
   830      MaybeSave();
   831    });
   832    t.Join();
   833  
   834    // Sleep for a bit before verifying the invalidation. The thread exit above
   835    // should cause the ptrace exception to be invalidated, but in Linux, this is
   836    // not done immediately. The YAMA exception is dropped during
   837    // __put_task_struct(), which occurs (at the earliest) one RCU grace period
   838    // after exit_notify() ==> release_task().
   839    SleepSafe(absl::Milliseconds(100));
   840  
   841    TEST_CHECK(CheckPtraceAttach(tracee_tid) == -1);
   842    TEST_PCHECK(errno == EPERM);
   843    _exit(0);
   844  }
   845  
   846  // Tests that YAMA exceptions store the tracer thread itself rather than the
   847  // thread group leader. Exceptions are preserved across exec in the tracer
   848  // thread, even if the thread group leader is terminated.
   849  TEST(PtraceTest, PrctlSetPtracerRespectsTracerThreadID) {
   850    SKIP_IF(ASSERT_NO_ERRNO_AND_VALUE(YamaPtraceScope()) != 1);
   851  
   852    // Use sockets to synchronize between tracer and tracee.
   853    int sockets[2];
   854    ASSERT_THAT(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets), SyscallSucceeds());
   855  
   856    pid_t const tracee_pid = fork();
   857    if (tracee_pid == 0) {
   858      TEST_PCHECK(close(sockets[1]) == 0);
   859      pid_t tracer_tid;
   860      TEST_PCHECK(read(sockets[0], &tracer_tid, sizeof(tracer_tid)) ==
   861                  sizeof(tracer_tid));
   862      MaybeSave();
   863  
   864      TEST_PCHECK(prctl(PR_SET_PTRACER, tracer_tid) == 0);
   865      MaybeSave();
   866      // Indicate that the prctl has been set.
   867      TEST_PCHECK(write(sockets[0], "x", 1) == 1);
   868      MaybeSave();
   869  
   870      while (true) {
   871        SleepSafe(absl::Seconds(1));
   872      }
   873    }
   874    ASSERT_THAT(tracee_pid, SyscallSucceeds());
   875    ASSERT_THAT(close(sockets[0]), SyscallSucceeds());
   876  
   877    // Allocate vector before forking (not async-signal-safe).
   878    ExecveArray const owned_child_argv = {
   879        "/proc/self/exe",
   880        "--ptrace_test_prctl_set_ptracer_respects_tracer_thread_id",
   881        "--ptrace_test_prctl_set_ptracer_respects_tracer_thread_id_tid",
   882        std::to_string(tracee_pid),
   883        "--ptrace_test_fd",
   884        std::to_string(sockets[1])};
   885    char* const* const child_argv = owned_child_argv.get();
   886  
   887    pid_t const tracer_pid = fork();
   888    if (tracer_pid == 0) {
   889      // This test will create a new thread in the child process.
   890      // pthread_create(2) isn't async-signal-safe, so we execve() first.
   891      execve(child_argv[0], child_argv, /* envp = */ nullptr);
   892      TEST_PCHECK_MSG(false, "Survived execve to test child");
   893    }
   894    ASSERT_THAT(tracer_pid, SyscallSucceeds());
   895  
   896    // Clean up tracer.
   897    int status;
   898    ASSERT_THAT(waitpid(tracer_pid, &status, 0), SyscallSucceeds());
   899    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   900        << " status " << status;
   901  
   902    // Clean up tracee.
   903    ASSERT_THAT(kill(tracee_pid, SIGKILL), SyscallSucceeds());
   904    ASSERT_THAT(waitpid(tracee_pid, &status, 0),
   905                SyscallSucceedsWithValue(tracee_pid));
   906    EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
   907        << " status " << status;
   908  }
   909  
   910  [[noreturn]] void RunPrctlSetPtracerRespectsTracerThreadID(int tracee_tid,
   911                                                             int fd) {
   912    // Create a separate thread for tracing (i.e., not the thread group
   913    // leader). After the subsequent execve(), the current thread group leader
   914    // will no longer be exist, but the YAMA exception installed with this
   915    // thread should still be valid.
   916    ScopedThread t([tracee_tid, fd] {
   917      pid_t const tracer_tid = gettid();
   918      TEST_PCHECK(write(fd, &tracer_tid, sizeof(tracer_tid)));
   919      MaybeSave();
   920  
   921      // Wait until the tracee has made the PR_SET_PTRACER prctl.
   922      char done;
   923      TEST_PCHECK(read(fd, &done, 1) == 1);
   924      MaybeSave();
   925  
   926      ExecveArray const owned_child_argv = {
   927          "/proc/self/exe", "--ptrace_test_trace_tid", std::to_string(tracee_tid),
   928          "--ptrace_test_fd", std::to_string(fd)};
   929      char* const* const child_argv = owned_child_argv.get();
   930  
   931      execve(child_argv[0], child_argv, /* envp = */ nullptr);
   932      TEST_PCHECK_MSG(false, "Survived execve to test child");
   933    });
   934    t.Join();
   935    TEST_CHECK_MSG(false, "Survived execve? (main)");
   936    _exit(1);
   937  }
   938  
   939  [[noreturn]] void RunTraceTID(int tracee_tid, int fd) {
   940    TEST_PCHECK(SetCapability(CAP_SYS_PTRACE, false).ok());
   941    TEST_PCHECK(CheckPtraceAttach(tracee_tid) == 0);
   942    _exit(0);
   943  }
   944  
   945  // Tests that removing a YAMA exception does not affect a tracer that is already
   946  // attached.
   947  TEST(PtraceTest, PrctlClearPtracerDoesNotAffectCurrentTracer) {
   948    SKIP_IF(ASSERT_NO_ERRNO_AND_VALUE(YamaPtraceScope()) != 1);
   949    AutoCapability cap(CAP_SYS_PTRACE, false);
   950  
   951    // Use sockets to synchronize between tracer and tracee.
   952    int sockets[2];
   953    ASSERT_THAT(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets), SyscallSucceeds());
   954  
   955    pid_t const tracee_pid = fork();
   956    if (tracee_pid == 0) {
   957      TEST_PCHECK(close(sockets[1]) == 0);
   958      TEST_PCHECK(prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY) == 0);
   959      MaybeSave();
   960      // Indicate that the prctl has been set.
   961      TEST_PCHECK(write(sockets[0], "x", 1) == 1);
   962      MaybeSave();
   963  
   964      // Wait until tracer has attached before clearing PR_SET_PTRACER.
   965      char done;
   966      TEST_PCHECK(read(sockets[0], &done, 1) == 1);
   967      MaybeSave();
   968  
   969      TEST_PCHECK(prctl(PR_SET_PTRACER, 0) == 0);
   970      MaybeSave();
   971      // Indicate that the prctl has been set.
   972      TEST_PCHECK(write(sockets[0], "x", 1) == 1);
   973      MaybeSave();
   974  
   975      while (true) {
   976        SleepSafe(absl::Seconds(1));
   977      }
   978    }
   979    ASSERT_THAT(tracee_pid, SyscallSucceeds());
   980    ASSERT_THAT(close(sockets[0]), SyscallSucceeds());
   981  
   982    std::string mem_path = "/proc/" + std::to_string(tracee_pid) + "/mem";
   983    pid_t const tracer_pid = fork();
   984    if (tracer_pid == 0) {
   985      // Wait until tracee has called prctl, or else we won't be able to attach.
   986      char done;
   987      TEST_PCHECK(read(sockets[1], &done, 1) == 1);
   988      MaybeSave();
   989  
   990      TEST_PCHECK(ptrace(PTRACE_ATTACH, tracee_pid, 0, 0) == 0);
   991      MaybeSave();
   992      // Indicate that we have attached.
   993      TEST_PCHECK(write(sockets[1], &done, 1) == 1);
   994      MaybeSave();
   995  
   996      // Block until tracee enters signal-delivery-stop as a result of the
   997      // SIGSTOP sent by PTRACE_ATTACH.
   998      int status;
   999      TEST_PCHECK(waitpid(tracee_pid, &status, 0) == tracee_pid);
  1000      MaybeSave();
  1001      TEST_CHECK(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP);
  1002      MaybeSave();
  1003  
  1004      TEST_PCHECK(ptrace(PTRACE_CONT, tracee_pid, 0, 0) == 0);
  1005      MaybeSave();
  1006  
  1007      // Wait until tracee has cleared PR_SET_PTRACER. Even though it was cleared,
  1008      // we should still be able to access /proc/[pid]/mem because we are already
  1009      // attached.
  1010      TEST_PCHECK(read(sockets[1], &done, 1) == 1);
  1011      MaybeSave();
  1012      TEST_PCHECK(open(mem_path.c_str(), O_RDONLY) != -1);
  1013      MaybeSave();
  1014      _exit(0);
  1015    }
  1016    ASSERT_THAT(tracer_pid, SyscallSucceeds());
  1017  
  1018    // Clean up tracer.
  1019    int status;
  1020    ASSERT_THAT(waitpid(tracer_pid, &status, 0), SyscallSucceeds());
  1021    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
  1022        << " status " << status;
  1023  
  1024    // Clean up tracee.
  1025    ASSERT_THAT(kill(tracee_pid, SIGKILL), SyscallSucceeds());
  1026    ASSERT_THAT(waitpid(tracee_pid, &status, 0),
  1027                SyscallSucceedsWithValue(tracee_pid));
  1028    EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
  1029        << " status " << status;
  1030  }
  1031  
  1032  TEST(PtraceTest, PrctlNotInherited) {
  1033    SKIP_IF(ASSERT_NO_ERRNO_AND_VALUE(YamaPtraceScope()) != 1);
  1034    AutoCapability cap(CAP_SYS_PTRACE, false);
  1035  
  1036    // Allow any ptracer. This should not affect the child processes.
  1037    ASSERT_THAT(prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY), SyscallSucceeds());
  1038  
  1039    pid_t const tracee_pid = fork();
  1040    if (tracee_pid == 0) {
  1041      while (true) {
  1042        SleepSafe(absl::Seconds(1));
  1043      }
  1044    }
  1045    ASSERT_THAT(tracee_pid, SyscallSucceeds());
  1046  
  1047    pid_t const tracer_pid = fork();
  1048    if (tracer_pid == 0) {
  1049      TEST_CHECK(CheckPtraceAttach(tracee_pid) == -1);
  1050      TEST_PCHECK(errno == EPERM);
  1051      _exit(0);
  1052    }
  1053    ASSERT_THAT(tracer_pid, SyscallSucceeds());
  1054  
  1055    // Clean up tracer.
  1056    int status;
  1057    ASSERT_THAT(waitpid(tracer_pid, &status, 0), SyscallSucceeds());
  1058    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
  1059        << " status " << status;
  1060  
  1061    // Clean up tracee.
  1062    ASSERT_THAT(kill(tracee_pid, SIGKILL), SyscallSucceeds());
  1063    ASSERT_THAT(waitpid(tracee_pid, &status, 0),
  1064                SyscallSucceedsWithValue(tracee_pid));
  1065    EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
  1066        << " status " << status;
  1067  }
  1068  
  1069  TEST(PtraceTest, AttachParent_PeekData_PokeData_SignalSuppression) {
  1070    // Yama prevents attaching to a parent. Skip the test if the scope is anything
  1071    // except disabled.
  1072    const int yama_scope = ASSERT_NO_ERRNO_AND_VALUE(YamaPtraceScope());
  1073    SKIP_IF(yama_scope > 1);
  1074    if (yama_scope == 1) {
  1075      // Allow child to trace us.
  1076      ASSERT_THAT(prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY), SyscallSucceeds());
  1077    }
  1078  
  1079    // Test PTRACE_POKE/PEEKDATA on both anonymous and file mappings.
  1080    const auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  1081    ASSERT_NO_ERRNO(Truncate(file.path(), kPageSize));
  1082    const FileDescriptor fd =
  1083        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR));
  1084    const auto file_mapping = ASSERT_NO_ERRNO_AND_VALUE(Mmap(
  1085        nullptr, kPageSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd.get(), 0));
  1086  
  1087    constexpr long kBeforePokeDataAnonValue = 10;
  1088    constexpr long kAfterPokeDataAnonValue = 20;
  1089    constexpr long kBeforePokeDataFileValue = 0;  // implicit, due to truncate()
  1090    constexpr long kAfterPokeDataFileValue = 30;
  1091  
  1092    volatile long anon_word = kBeforePokeDataAnonValue;
  1093    auto* file_word_ptr = static_cast<volatile long*>(file_mapping.ptr());
  1094  
  1095    pid_t const child_pid = fork();
  1096    if (child_pid == 0) {
  1097      // In child process.
  1098  
  1099      // Attach to the parent.
  1100      pid_t const parent_pid = getppid();
  1101      TEST_PCHECK(ptrace(PTRACE_ATTACH, parent_pid, 0, 0) == 0);
  1102      MaybeSave();
  1103  
  1104      // Block until the parent enters signal-delivery-stop as a result of the
  1105      // SIGSTOP sent by PTRACE_ATTACH.
  1106      int status;
  1107      TEST_PCHECK(waitpid(parent_pid, &status, 0) == parent_pid);
  1108      MaybeSave();
  1109      TEST_CHECK(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP);
  1110  
  1111      // Replace the value of anon_word in the parent process with
  1112      // kAfterPokeDataAnonValue.
  1113      long parent_word = ptrace(PTRACE_PEEKDATA, parent_pid, &anon_word, 0);
  1114      MaybeSave();
  1115      TEST_CHECK(parent_word == kBeforePokeDataAnonValue);
  1116      TEST_PCHECK(ptrace(PTRACE_POKEDATA, parent_pid, &anon_word,
  1117                         kAfterPokeDataAnonValue) == 0);
  1118      MaybeSave();
  1119  
  1120      // Replace the value pointed to by file_word_ptr in the mapped file with
  1121      // kAfterPokeDataFileValue, via the parent process' mapping.
  1122      parent_word = ptrace(PTRACE_PEEKDATA, parent_pid, file_word_ptr, 0);
  1123      MaybeSave();
  1124      TEST_CHECK(parent_word == kBeforePokeDataFileValue);
  1125      TEST_PCHECK(ptrace(PTRACE_POKEDATA, parent_pid, file_word_ptr,
  1126                         kAfterPokeDataFileValue) == 0);
  1127      MaybeSave();
  1128  
  1129      // Detach from the parent and suppress the SIGSTOP. If the SIGSTOP is not
  1130      // suppressed, the parent will hang in group-stop, causing the test to time
  1131      // out.
  1132      TEST_PCHECK(ptrace(PTRACE_DETACH, parent_pid, 0, 0) == 0);
  1133      MaybeSave();
  1134      _exit(0);
  1135    }
  1136    // In parent process.
  1137    ASSERT_THAT(child_pid, SyscallSucceeds());
  1138  
  1139    // Wait for the child to complete.
  1140    int status;
  1141    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1142                SyscallSucceedsWithValue(child_pid));
  1143    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
  1144        << " status " << status;
  1145  
  1146    // Check that the child's PTRACE_POKEDATA was effective.
  1147    EXPECT_EQ(kAfterPokeDataAnonValue, anon_word);
  1148    EXPECT_EQ(kAfterPokeDataFileValue, *file_word_ptr);
  1149  }
  1150  
  1151  TEST(PtraceTest, GetSigMask) {
  1152    // glibc and the Linux kernel define a sigset_t with different sizes. To avoid
  1153    // creating a kernel_sigset_t and recreating all the modification functions
  1154    // (sigemptyset, etc), we just hardcode the kernel sigset size.
  1155    constexpr int kSizeofKernelSigset = 8;
  1156    constexpr int kBlockSignal = SIGUSR1;
  1157    sigset_t blocked;
  1158    sigemptyset(&blocked);
  1159    sigaddset(&blocked, kBlockSignal);
  1160  
  1161    pid_t const child_pid = fork();
  1162    if (child_pid == 0) {
  1163      // In child process.
  1164  
  1165      // Install a signal handler for kBlockSignal to avoid termination and block
  1166      // it.
  1167      TEST_PCHECK(signal(
  1168                      kBlockSignal, +[](int signo) {}) != SIG_ERR);
  1169      MaybeSave();
  1170      TEST_PCHECK(sigprocmask(SIG_SETMASK, &blocked, nullptr) == 0);
  1171      MaybeSave();
  1172  
  1173      // Enable tracing.
  1174      TEST_PCHECK(ptrace(PTRACE_TRACEME, 0, 0, 0) == 0);
  1175      MaybeSave();
  1176  
  1177      // This should be blocked.
  1178      RaiseSignal(kBlockSignal);
  1179  
  1180      // This should be suppressed by parent, who will change signal mask in the
  1181      // meantime, which means kBlockSignal should be delivered once this resumes.
  1182      RaiseSignal(SIGSTOP);
  1183  
  1184      _exit(0);
  1185    }
  1186    // In parent process.
  1187    ASSERT_THAT(child_pid, SyscallSucceeds());
  1188  
  1189    // Wait for the child to send itself SIGSTOP and enter signal-delivery-stop.
  1190    int status;
  1191    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1192                SyscallSucceedsWithValue(child_pid));
  1193    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
  1194        << " status " << status;
  1195  
  1196    // Get current signal mask.
  1197    sigset_t set;
  1198    EXPECT_THAT(ptrace(kPtraceGetSigMask, child_pid, kSizeofKernelSigset, &set),
  1199                SyscallSucceeds());
  1200    EXPECT_THAT(blocked, EqualsSigset(set));
  1201  
  1202    // Try to get current signal mask with bad size argument.
  1203    EXPECT_THAT(ptrace(kPtraceGetSigMask, child_pid, 0, nullptr),
  1204                SyscallFailsWithErrno(EINVAL));
  1205  
  1206    // Try to set bad signal mask.
  1207    sigset_t* bad_addr = reinterpret_cast<sigset_t*>(-1);
  1208    EXPECT_THAT(
  1209        ptrace(kPtraceSetSigMask, child_pid, kSizeofKernelSigset, bad_addr),
  1210        SyscallFailsWithErrno(EFAULT));
  1211  
  1212    // Set signal mask to empty set.
  1213    sigset_t set1;
  1214    sigemptyset(&set1);
  1215    EXPECT_THAT(ptrace(kPtraceSetSigMask, child_pid, kSizeofKernelSigset, &set1),
  1216                SyscallSucceeds());
  1217  
  1218    // Suppress SIGSTOP and resume the child. It should re-enter
  1219    // signal-delivery-stop for kBlockSignal.
  1220    ASSERT_THAT(ptrace(PTRACE_CONT, child_pid, 0, 0), SyscallSucceeds());
  1221    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1222                SyscallSucceedsWithValue(child_pid));
  1223    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == kBlockSignal)
  1224        << " status " << status;
  1225  
  1226    ASSERT_THAT(ptrace(PTRACE_CONT, child_pid, 0, 0), SyscallSucceeds());
  1227    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1228                SyscallSucceedsWithValue(child_pid));
  1229    // Let's see that process exited normally.
  1230    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
  1231        << " status " << status;
  1232  }
  1233  
  1234  TEST(PtraceTest, GetSiginfo_SetSiginfo_SignalInjection) {
  1235    constexpr int kOriginalSigno = SIGUSR1;
  1236    constexpr int kInjectedSigno = SIGUSR2;
  1237  
  1238    pid_t const child_pid = fork();
  1239    if (child_pid == 0) {
  1240      // In child process.
  1241  
  1242      // Override all signal handlers.
  1243      struct sigaction sa = {};
  1244      sa.sa_handler = +[](int signo) { _exit(signo); };
  1245      TEST_PCHECK(sigfillset(&sa.sa_mask) == 0);
  1246      for (int signo = 1; signo < 32; signo++) {
  1247        if (signo == SIGKILL || signo == SIGSTOP) {
  1248          continue;
  1249        }
  1250        TEST_PCHECK(sigaction(signo, &sa, nullptr) == 0);
  1251      }
  1252      for (int signo = SIGRTMIN; signo <= SIGRTMAX; signo++) {
  1253        TEST_PCHECK(sigaction(signo, &sa, nullptr) == 0);
  1254      }
  1255  
  1256      // Unblock all signals.
  1257      TEST_PCHECK(sigprocmask(SIG_UNBLOCK, &sa.sa_mask, nullptr) == 0);
  1258      MaybeSave();
  1259  
  1260      // Send ourselves kOriginalSignal while ptraced and exit with the signal we
  1261      // actually receive via the signal handler, if any, or 0 if we don't receive
  1262      // a signal.
  1263      TEST_PCHECK(ptrace(PTRACE_TRACEME, 0, 0, 0) == 0);
  1264      MaybeSave();
  1265      RaiseSignal(kOriginalSigno);
  1266      _exit(0);
  1267    }
  1268    // In parent process.
  1269    ASSERT_THAT(child_pid, SyscallSucceeds());
  1270  
  1271    // Wait for the child to send itself kOriginalSigno and enter
  1272    // signal-delivery-stop.
  1273    int status;
  1274    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1275                SyscallSucceedsWithValue(child_pid));
  1276    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == kOriginalSigno)
  1277        << " status " << status;
  1278  
  1279    siginfo_t siginfo = {};
  1280    ASSERT_THAT(ptrace(PTRACE_GETSIGINFO, child_pid, 0, &siginfo),
  1281                SyscallSucceeds());
  1282    EXPECT_EQ(kOriginalSigno, siginfo.si_signo);
  1283    EXPECT_EQ(SI_TKILL, siginfo.si_code);
  1284  
  1285    // Replace the signal with kInjectedSigno, and check that the child exits
  1286    // with kInjectedSigno, indicating that signal injection was successful.
  1287    siginfo.si_signo = kInjectedSigno;
  1288    ASSERT_THAT(ptrace(PTRACE_SETSIGINFO, child_pid, 0, &siginfo),
  1289                SyscallSucceeds());
  1290    ASSERT_THAT(ptrace(PTRACE_DETACH, child_pid, 0, kInjectedSigno),
  1291                SyscallSucceeds());
  1292    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1293                SyscallSucceedsWithValue(child_pid));
  1294    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == kInjectedSigno)
  1295        << " status " << status;
  1296  }
  1297  
  1298  TEST(PtraceTest, SIGKILLDoesNotCauseSignalDeliveryStop) {
  1299    pid_t const child_pid = fork();
  1300    if (child_pid == 0) {
  1301      // In child process.
  1302      TEST_PCHECK(ptrace(PTRACE_TRACEME, 0, 0, 0) == 0);
  1303      MaybeSave();
  1304      RaiseSignal(SIGKILL);
  1305      TEST_CHECK_MSG(false, "Survived SIGKILL?");
  1306      _exit(1);
  1307    }
  1308    // In parent process.
  1309    ASSERT_THAT(child_pid, SyscallSucceeds());
  1310  
  1311    // Expect the child to die to SIGKILL without entering signal-delivery-stop.
  1312    int status;
  1313    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1314                SyscallSucceedsWithValue(child_pid));
  1315    EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
  1316        << " status " << status;
  1317  }
  1318  
  1319  TEST(PtraceTest, PtraceKill) {
  1320    constexpr int kOriginalSigno = SIGUSR1;
  1321  
  1322    pid_t const child_pid = fork();
  1323    if (child_pid == 0) {
  1324      // In child process.
  1325      TEST_PCHECK(ptrace(PTRACE_TRACEME, 0, 0, 0) == 0);
  1326      MaybeSave();
  1327  
  1328      // PTRACE_KILL only works if tracee has entered signal-delivery-stop.
  1329      RaiseSignal(kOriginalSigno);
  1330      TEST_CHECK_MSG(false, "Failed to kill the process?");
  1331      _exit(0);
  1332    }
  1333    // In parent process.
  1334    ASSERT_THAT(child_pid, SyscallSucceeds());
  1335  
  1336    // Wait for the child to send itself kOriginalSigno and enter
  1337    // signal-delivery-stop.
  1338    int status;
  1339    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1340                SyscallSucceedsWithValue(child_pid));
  1341    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == kOriginalSigno)
  1342        << " status " << status;
  1343  
  1344    ASSERT_THAT(ptrace(PTRACE_KILL, child_pid, 0, 0), SyscallSucceeds());
  1345  
  1346    // Expect the child to die with SIGKILL.
  1347    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1348                SyscallSucceedsWithValue(child_pid));
  1349    EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
  1350        << " status " << status;
  1351  }
  1352  
  1353  TEST(PtraceTest, GetRegSet) {
  1354    pid_t const child_pid = fork();
  1355    if (child_pid == 0) {
  1356      // In child process.
  1357  
  1358      // Enable tracing.
  1359      TEST_PCHECK(ptrace(PTRACE_TRACEME, 0, 0, 0) == 0);
  1360      MaybeSave();
  1361  
  1362      // Use kill explicitly because we check the syscall argument register below.
  1363      kill(getpid(), SIGSTOP);
  1364  
  1365      _exit(0);
  1366    }
  1367    // In parent process.
  1368    ASSERT_THAT(child_pid, SyscallSucceeds());
  1369  
  1370    // Wait for the child to send itself SIGSTOP and enter signal-delivery-stop.
  1371    int status;
  1372    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1373                SyscallSucceedsWithValue(child_pid));
  1374    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
  1375        << " status " << status;
  1376  
  1377    // Get the general registers.
  1378    struct user_regs_struct regs;
  1379    struct iovec iov;
  1380    iov.iov_base = &regs;
  1381    iov.iov_len = sizeof(regs);
  1382    EXPECT_THAT(ptrace(PTRACE_GETREGSET, child_pid, NT_PRSTATUS, &iov),
  1383                SyscallSucceeds());
  1384  
  1385    // Read exactly the full register set.
  1386    EXPECT_EQ(iov.iov_len, sizeof(regs));
  1387  
  1388  #if defined(__x86_64__)
  1389    // Child called kill(2), with SIGSTOP as arg 2.
  1390    EXPECT_EQ(regs.rsi, SIGSTOP);
  1391  #elif defined(__aarch64__)
  1392    EXPECT_EQ(regs.regs[1], SIGSTOP);
  1393  #endif
  1394  
  1395    // Suppress SIGSTOP and resume the child.
  1396    ASSERT_THAT(ptrace(PTRACE_CONT, child_pid, 0, 0), SyscallSucceeds());
  1397    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1398                SyscallSucceedsWithValue(child_pid));
  1399    // Let's see that process exited normally.
  1400    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
  1401        << " status " << status;
  1402  }
  1403  #if defined(__x86_64__)
  1404  #define SYSNO_STR1(x) #x
  1405  #define SYSNO_STR(x) SYSNO_STR1(x)
  1406  
  1407  // Check that ptrace works properly when a target process is stopped on a
  1408  // system call that is handled via the fast path.
  1409  TEST(PtraceTest, ChangeRegSetInOptSyscall) {
  1410    constexpr uint64_t kTestRet = 0x111;
  1411    constexpr uint64_t kTestRbx1 = 0x333;
  1412    constexpr uint64_t kTestRbx2 = 0x333;
  1413    constexpr uint64_t kTestRdi = 0x555;
  1414  
  1415    pid_t const child_pid = fork();
  1416    if (child_pid == 0) {
  1417      // In child process.
  1418      uint64_t ret, rbx = 0, rdi = kTestRdi;
  1419  
  1420      // Enable tracing.
  1421      TEST_PCHECK(ptrace(PTRACE_TRACEME, 0, 0, 0) == 0);
  1422      MaybeSave();
  1423  
  1424      // Use kill explicitly because we check the syscall argument register below.
  1425      kill(getpid(), SIGSTOP);
  1426  
  1427      // A tested syscall has to be triggered twice, because the first call
  1428      // doesn't trigger the fast path.
  1429      for (int i = 0; i < 2; i++) {
  1430        if (i == 1) rbx = kTestRbx1;
  1431        __asm__ __volatile__(
  1432                           "movl $" SYSNO_STR(SYS_getpid) ", %%eax\n"
  1433                           "syscall\n"
  1434                         : "=a"(ret), "=b"(rbx)
  1435                         : "b"(rbx), "D"(rdi)
  1436                         : "rcx", "r11", "memory");
  1437      }
  1438  
  1439      TEST_CHECK(ret == kTestRet);
  1440      TEST_CHECK(rbx == kTestRbx2);
  1441  
  1442      _exit(0);
  1443    }
  1444    // In parent process.
  1445    ASSERT_THAT(child_pid, SyscallSucceeds());
  1446  
  1447    // Wait for the child to send itself SIGSTOP and enter signal-delivery-stop.
  1448    int status;
  1449    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1450                SyscallSucceedsWithValue(child_pid));
  1451    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
  1452        << " status " << status;
  1453  
  1454    // Stop the child in the second getpid syscall.
  1455    for (int i = 0; i < 2; i++) {
  1456      ASSERT_THAT(ptrace(PTRACE_SYSEMU, child_pid, 0, 0), SyscallSucceeds());
  1457      ASSERT_THAT(waitpid(child_pid, &status, 0),
  1458                  SyscallSucceedsWithValue(child_pid));
  1459    }
  1460  
  1461    // Get the general registers.
  1462    struct user_regs_struct regs;
  1463    struct iovec iov;
  1464    iov.iov_base = &regs;
  1465    iov.iov_len = sizeof(regs);
  1466    EXPECT_THAT(ptrace(PTRACE_GETREGSET, child_pid, NT_PRSTATUS, &iov),
  1467                SyscallSucceeds());
  1468  
  1469    // Read exactly the full register set.
  1470    EXPECT_EQ(iov.iov_len, sizeof(regs));
  1471  
  1472    EXPECT_EQ(regs.rax, -ENOSYS);
  1473    EXPECT_EQ(regs.orig_rax, SYS_getpid);
  1474    EXPECT_EQ(regs.rdi, kTestRdi);
  1475    EXPECT_EQ(regs.rbx, kTestRbx1);
  1476  
  1477    regs.rbx = kTestRbx2;
  1478    regs.rax = kTestRet;
  1479    EXPECT_THAT(ptrace(PTRACE_SETREGSET, child_pid, NT_PRSTATUS, &iov),
  1480                SyscallSucceeds());
  1481  
  1482    ASSERT_THAT(ptrace(PTRACE_CONT, child_pid, 0, 0), SyscallSucceeds());
  1483    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1484                SyscallSucceedsWithValue(child_pid));
  1485    // Let's see that process exited normally.
  1486    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
  1487        << " status " << status;
  1488  }
  1489  #endif
  1490  
  1491  TEST(PtraceTest, AttachingConvertsGroupStopToPtraceStop) {
  1492    pid_t const child_pid = fork();
  1493    if (child_pid == 0) {
  1494      // In child process.
  1495      while (true) {
  1496        pause();
  1497      }
  1498    }
  1499    // In parent process.
  1500    ASSERT_THAT(child_pid, SyscallSucceeds());
  1501  
  1502    // SIGSTOP the child and wait for it to stop.
  1503    ASSERT_THAT(kill(child_pid, SIGSTOP), SyscallSucceeds());
  1504    int status;
  1505    ASSERT_THAT(waitpid(child_pid, &status, WUNTRACED),
  1506                SyscallSucceedsWithValue(child_pid));
  1507    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
  1508        << " status " << status;
  1509  
  1510    // Attach to the child and expect it to re-enter a traced group-stop despite
  1511    // already being stopped.
  1512    ASSERT_THAT(ptrace(PTRACE_ATTACH, child_pid, 0, 0), SyscallSucceeds());
  1513    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1514                SyscallSucceedsWithValue(child_pid));
  1515    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
  1516        << " status " << status;
  1517  
  1518    // Verify that the child is ptrace-stopped by checking that it can receive
  1519    // ptrace commands requiring a ptrace-stop.
  1520    EXPECT_THAT(ptrace(PTRACE_SETOPTIONS, child_pid, 0, 0), SyscallSucceeds());
  1521  
  1522    // Group-stop is distinguished from signal-delivery-stop by PTRACE_GETSIGINFO
  1523    // failing with EINVAL.
  1524    siginfo_t siginfo = {};
  1525    EXPECT_THAT(ptrace(PTRACE_GETSIGINFO, child_pid, 0, &siginfo),
  1526                SyscallFailsWithErrno(EINVAL));
  1527  
  1528    // Detach from the child and expect it to stay stopped without a notification.
  1529    ASSERT_THAT(ptrace(PTRACE_DETACH, child_pid, 0, 0), SyscallSucceeds());
  1530    ASSERT_THAT(waitpid(child_pid, &status, WUNTRACED | WNOHANG),
  1531                SyscallSucceedsWithValue(0));
  1532  
  1533    // Sending it SIGCONT should cause it to leave its stop.
  1534    ASSERT_THAT(kill(child_pid, SIGCONT), SyscallSucceeds());
  1535    ASSERT_THAT(waitpid(child_pid, &status, WCONTINUED),
  1536                SyscallSucceedsWithValue(child_pid));
  1537    EXPECT_TRUE(WIFCONTINUED(status)) << " status " << status;
  1538  
  1539    // Clean up the child.
  1540    ASSERT_THAT(kill(child_pid, SIGKILL), SyscallSucceeds());
  1541    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1542                SyscallSucceedsWithValue(child_pid));
  1543    EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
  1544        << " status " << status;
  1545  }
  1546  
  1547  // Fixture for tests parameterized by whether or not to use PTRACE_O_TRACEEXEC.
  1548  class PtraceExecveTest : public ::testing::TestWithParam<bool> {
  1549   protected:
  1550    bool TraceExec() const { return GetParam(); }
  1551  };
  1552  
  1553  TEST_P(PtraceExecveTest, Execve_GetRegs_PeekUser_SIGKILL_TraceClone_TraceExit) {
  1554    ExecveArray const owned_child_argv = {"/proc/self/exe",
  1555                                          "--ptrace_test_execve_child"};
  1556    char* const* const child_argv = owned_child_argv.get();
  1557  
  1558    pid_t const child_pid = fork();
  1559    if (child_pid == 0) {
  1560      // In child process. The test relies on calling execve() in a non-leader
  1561      // thread; pthread_create() isn't async-signal-safe, so the safest way to
  1562      // do this is to execve() first, then enable tracing and run the expected
  1563      // child process behavior in the new subprocess.
  1564      execve(child_argv[0], child_argv, /* envp = */ nullptr);
  1565      TEST_PCHECK_MSG(false, "Survived execve to test child");
  1566    }
  1567    // In parent process.
  1568    ASSERT_THAT(child_pid, SyscallSucceeds());
  1569  
  1570    // Wait for the child to send itself SIGSTOP and enter signal-delivery-stop.
  1571    int status;
  1572    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1573                SyscallSucceedsWithValue(child_pid));
  1574    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
  1575        << " status " << status;
  1576  
  1577    // Enable PTRACE_O_TRACECLONE so we can get the ID of the child's non-leader
  1578    // thread, PTRACE_O_TRACEEXIT so we can observe the leader's death, and
  1579    // PTRACE_O_TRACEEXEC if required by the test. (The leader doesn't call
  1580    // execve, but options should be inherited across clone.)
  1581    long opts = PTRACE_O_TRACECLONE | PTRACE_O_TRACEEXIT;
  1582    if (TraceExec()) {
  1583      opts |= PTRACE_O_TRACEEXEC;
  1584    }
  1585    ASSERT_THAT(ptrace(PTRACE_SETOPTIONS, child_pid, 0, opts), SyscallSucceeds());
  1586  
  1587    // Suppress the SIGSTOP and wait for the child's leader thread to report
  1588    // PTRACE_EVENT_CLONE. Get the new thread's ID from the event.
  1589    ASSERT_THAT(ptrace(PTRACE_CONT, child_pid, 0, 0), SyscallSucceeds());
  1590    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1591                SyscallSucceedsWithValue(child_pid));
  1592    EXPECT_EQ(SIGTRAP | (PTRACE_EVENT_CLONE << 8), status >> 8);
  1593    unsigned long eventmsg;
  1594    ASSERT_THAT(ptrace(PTRACE_GETEVENTMSG, child_pid, 0, &eventmsg),
  1595                SyscallSucceeds());
  1596    pid_t const nonleader_tid = eventmsg;
  1597    pid_t const leader_tid = child_pid;
  1598  
  1599    // The new thread should be ptraced and in signal-delivery-stop by SIGSTOP due
  1600    // to PTRACE_O_TRACECLONE.
  1601    //
  1602    // Before bf959931ddb88c4e4366e96dd22e68fa0db9527c "wait/ptrace: assume __WALL
  1603    // if the child is traced" (4.7) , waiting on it requires __WCLONE since, as a
  1604    // non-leader, its termination signal is 0. After, a standard wait is
  1605    // sufficient.
  1606    ASSERT_THAT(waitpid(nonleader_tid, &status, __WCLONE),
  1607                SyscallSucceedsWithValue(nonleader_tid));
  1608    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
  1609        << " status " << status;
  1610  
  1611    // Resume both child threads.
  1612    for (pid_t const tid : {leader_tid, nonleader_tid}) {
  1613      ASSERT_THAT(ptrace(PTRACE_CONT, tid, 0, 0), SyscallSucceeds());
  1614    }
  1615  
  1616    // The non-leader child thread should call execve, causing the leader thread
  1617    // to enter PTRACE_EVENT_EXIT with an apparent exit code of 0. At this point,
  1618    // the leader has not yet exited, so the non-leader should be blocked in
  1619    // execve.
  1620    ASSERT_THAT(waitpid(leader_tid, &status, 0),
  1621                SyscallSucceedsWithValue(leader_tid));
  1622    EXPECT_EQ(SIGTRAP | (PTRACE_EVENT_EXIT << 8), status >> 8);
  1623    ASSERT_THAT(ptrace(PTRACE_GETEVENTMSG, leader_tid, 0, &eventmsg),
  1624                SyscallSucceeds());
  1625    EXPECT_TRUE(WIFEXITED(eventmsg) && WEXITSTATUS(eventmsg) == 0)
  1626        << " eventmsg " << eventmsg;
  1627    EXPECT_THAT(waitpid(nonleader_tid, &status, __WCLONE | WNOHANG),
  1628                SyscallSucceedsWithValue(0));
  1629  
  1630    // Allow the leader to continue exiting. This should allow the non-leader to
  1631    // complete its execve, causing the original leader to be reaped without
  1632    // further notice and the non-leader to steal its ID.
  1633    ASSERT_THAT(ptrace(PTRACE_CONT, leader_tid, 0, 0), SyscallSucceeds());
  1634    ASSERT_THAT(waitpid(leader_tid, &status, 0),
  1635                SyscallSucceedsWithValue(leader_tid));
  1636    if (TraceExec()) {
  1637      // If PTRACE_O_TRACEEXEC was enabled, the execing thread should be in
  1638      // PTRACE_EVENT_EXEC-stop, with the event message set to its old thread ID.
  1639      EXPECT_EQ(SIGTRAP | (PTRACE_EVENT_EXEC << 8), status >> 8);
  1640      ASSERT_THAT(ptrace(PTRACE_GETEVENTMSG, leader_tid, 0, &eventmsg),
  1641                  SyscallSucceeds());
  1642      EXPECT_EQ(nonleader_tid, eventmsg);
  1643    } else {
  1644      // Otherwise, the execing thread should have received SIGTRAP and should now
  1645      // be in signal-delivery-stop.
  1646      EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP)
  1647          << " status " << status;
  1648    }
  1649  
  1650  #ifdef __x86_64__
  1651    {
  1652      // CS should be 0x33, indicating an 64-bit binary.
  1653      constexpr uint64_t kAMD64UserCS = 0x33;
  1654      EXPECT_THAT(ptrace(PTRACE_PEEKUSER, leader_tid,
  1655                         offsetof(struct user_regs_struct, cs), 0),
  1656                  SyscallSucceedsWithValue(kAMD64UserCS));
  1657      struct user_regs_struct regs = {};
  1658      ASSERT_THAT(ptrace(PTRACE_GETREGS, leader_tid, 0, &regs),
  1659                  SyscallSucceeds());
  1660      EXPECT_EQ(kAMD64UserCS, regs.cs);
  1661    }
  1662  #endif  // defined(__x86_64__)
  1663  
  1664    // PTRACE_O_TRACEEXIT should have been inherited across execve. Send SIGKILL,
  1665    // which should end the PTRACE_EVENT_EXEC-stop or signal-delivery-stop and
  1666    // leave the child in PTRACE_EVENT_EXIT-stop.
  1667    ASSERT_THAT(kill(leader_tid, SIGKILL), SyscallSucceeds());
  1668    ASSERT_THAT(waitpid(leader_tid, &status, 0),
  1669                SyscallSucceedsWithValue(leader_tid));
  1670    EXPECT_EQ(SIGTRAP | (PTRACE_EVENT_EXIT << 8), status >> 8);
  1671    ASSERT_THAT(ptrace(PTRACE_GETEVENTMSG, leader_tid, 0, &eventmsg),
  1672                SyscallSucceeds());
  1673    EXPECT_TRUE(WIFSIGNALED(eventmsg) && WTERMSIG(eventmsg) == SIGKILL)
  1674        << " eventmsg " << eventmsg;
  1675  
  1676    // End the PTRACE_EVENT_EXIT stop, allowing the child to exit.
  1677    ASSERT_THAT(ptrace(PTRACE_CONT, leader_tid, 0, 0), SyscallSucceeds());
  1678    ASSERT_THAT(waitpid(leader_tid, &status, 0),
  1679                SyscallSucceedsWithValue(leader_tid));
  1680    EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
  1681        << " status " << status;
  1682  }
  1683  
  1684  [[noreturn]] void RunExecveChild() {
  1685    // Enable tracing, then raise SIGSTOP and expect our parent to suppress it.
  1686    TEST_PCHECK(ptrace(PTRACE_TRACEME, 0, 0, 0) == 0);
  1687    MaybeSave();
  1688    RaiseSignal(SIGSTOP);
  1689    MaybeSave();
  1690  
  1691    // Call execve() in a non-leader thread. As long as execve() succeeds, what
  1692    // exactly we execve() shouldn't really matter, since the tracer should kill
  1693    // us after execve() completes.
  1694    ScopedThread t([&] {
  1695      ExecveArray const owned_child_argv = {"/proc/self/exe",
  1696                                            "--this_flag_shouldnt_exist"};
  1697      char* const* const child_argv = owned_child_argv.get();
  1698      execve(child_argv[0], child_argv, /* envp = */ nullptr);
  1699      TEST_PCHECK_MSG(false, "Survived execve? (thread)");
  1700    });
  1701    t.Join();
  1702    TEST_CHECK_MSG(false, "Survived execve? (main)");
  1703    _exit(1);
  1704  }
  1705  
  1706  INSTANTIATE_TEST_SUITE_P(TraceExec, PtraceExecveTest, ::testing::Bool());
  1707  
  1708  // This test has expectations on when syscall-enter/exit-stops occur that are
  1709  // violated if saving occurs, since saving interrupts all syscalls, causing
  1710  // premature syscall-exit.
  1711  TEST(PtraceTest, ExitWhenParentIsNotTracer_Syscall_TraceVfork_TraceVforkDone) {
  1712    constexpr int kExitTraceeExitCode = 99;
  1713  
  1714    pid_t const child_pid = fork();
  1715    if (child_pid == 0) {
  1716      // In child process.
  1717  
  1718      // Block SIGCHLD so it doesn't interrupt wait4.
  1719      sigset_t mask;
  1720      TEST_PCHECK(sigemptyset(&mask) == 0);
  1721      TEST_PCHECK(sigaddset(&mask, SIGCHLD) == 0);
  1722      TEST_PCHECK(sigprocmask(SIG_SETMASK, &mask, nullptr) == 0);
  1723      MaybeSave();
  1724  
  1725      // Enable tracing, then raise SIGSTOP and expect our parent to suppress it.
  1726      TEST_PCHECK(ptrace(PTRACE_TRACEME, 0, 0, 0) == 0);
  1727      MaybeSave();
  1728      RaiseSignal(SIGSTOP);
  1729      MaybeSave();
  1730  
  1731      // Spawn a vfork child that exits immediately, and reap it. Don't save
  1732      // after vfork since the parent expects to see wait4 as the next syscall.
  1733      pid_t const pid = vfork();
  1734      if (pid == 0) {
  1735        _exit(kExitTraceeExitCode);
  1736      }
  1737      TEST_PCHECK_MSG(pid > 0, "vfork failed");
  1738  
  1739      int status;
  1740      TEST_PCHECK(wait4(pid, &status, 0, nullptr) > 0);
  1741      MaybeSave();
  1742      TEST_CHECK(WIFEXITED(status) && WEXITSTATUS(status) == kExitTraceeExitCode);
  1743      _exit(0);
  1744    }
  1745    // In parent process.
  1746    ASSERT_THAT(child_pid, SyscallSucceeds());
  1747  
  1748    // Wait for the child to send itself SIGSTOP and enter signal-delivery-stop.
  1749    int status;
  1750    ASSERT_THAT(child_pid, SyscallSucceeds());
  1751    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1752                SyscallSucceedsWithValue(child_pid));
  1753    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
  1754        << " status " << status;
  1755  
  1756    // Enable PTRACE_O_TRACEVFORK so we can get the ID of the grandchild,
  1757    // PTRACE_O_TRACEVFORKDONE so we can observe PTRACE_EVENT_VFORK_DONE, and
  1758    // PTRACE_O_TRACESYSGOOD so syscall-enter/exit-stops are unambiguously
  1759    // indicated by a stop signal of SIGTRAP|0x80 rather than just SIGTRAP.
  1760    ASSERT_THAT(ptrace(PTRACE_SETOPTIONS, child_pid, 0,
  1761                       PTRACE_O_TRACEVFORK | PTRACE_O_TRACEVFORKDONE |
  1762                           PTRACE_O_TRACESYSGOOD),
  1763                SyscallSucceeds());
  1764  
  1765    // Suppress the SIGSTOP and wait for the child to report PTRACE_EVENT_VFORK.
  1766    // Get the new process' ID from the event.
  1767    ASSERT_THAT(ptrace(PTRACE_CONT, child_pid, 0, 0), SyscallSucceeds());
  1768    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1769                SyscallSucceedsWithValue(child_pid));
  1770    EXPECT_EQ(SIGTRAP | (PTRACE_EVENT_VFORK << 8), status >> 8);
  1771    unsigned long eventmsg;
  1772    ASSERT_THAT(ptrace(PTRACE_GETEVENTMSG, child_pid, 0, &eventmsg),
  1773                SyscallSucceeds());
  1774    pid_t const grandchild_pid = eventmsg;
  1775  
  1776    // The grandchild should be traced by us and in signal-delivery-stop by
  1777    // SIGSTOP due to PTRACE_O_TRACEVFORK. This allows us to wait on it even
  1778    // though we're not its parent.
  1779    ASSERT_THAT(waitpid(grandchild_pid, &status, 0),
  1780                SyscallSucceedsWithValue(grandchild_pid));
  1781    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
  1782        << " status " << status;
  1783  
  1784    // Resume the child with PTRACE_SYSCALL. Since the grandchild is still in
  1785    // signal-delivery-stop, the child should remain in vfork() waiting for the
  1786    // grandchild to exec or exit.
  1787    ASSERT_THAT(ptrace(PTRACE_SYSCALL, child_pid, 0, 0), SyscallSucceeds());
  1788    absl::SleepFor(absl::Seconds(1));
  1789    ASSERT_THAT(waitpid(child_pid, &status, WNOHANG),
  1790                SyscallSucceedsWithValue(0));
  1791  
  1792    // Suppress the grandchild's SIGSTOP and wait for the grandchild to exit. Pass
  1793    // WNOWAIT to waitid() so that we don't acknowledge the grandchild's exit yet.
  1794    ASSERT_THAT(ptrace(PTRACE_CONT, grandchild_pid, 0, 0), SyscallSucceeds());
  1795    siginfo_t siginfo = {};
  1796    ASSERT_THAT(waitid(P_PID, grandchild_pid, &siginfo, WEXITED | WNOWAIT),
  1797                SyscallSucceeds());
  1798    EXPECT_EQ(SIGCHLD, siginfo.si_signo);
  1799    EXPECT_EQ(CLD_EXITED, siginfo.si_code);
  1800    EXPECT_EQ(kExitTraceeExitCode, siginfo.si_status);
  1801    EXPECT_EQ(grandchild_pid, siginfo.si_pid);
  1802    EXPECT_EQ(getuid(), siginfo.si_uid);
  1803  
  1804    // The child should now be in PTRACE_EVENT_VFORK_DONE stop. The event
  1805    // message should still be the grandchild's PID.
  1806    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1807                SyscallSucceedsWithValue(child_pid));
  1808    EXPECT_EQ(SIGTRAP | (PTRACE_EVENT_VFORK_DONE << 8), status >> 8);
  1809    ASSERT_THAT(ptrace(PTRACE_GETEVENTMSG, child_pid, 0, &eventmsg),
  1810                SyscallSucceeds());
  1811    EXPECT_EQ(grandchild_pid, eventmsg);
  1812  
  1813    // Resume the child with PTRACE_SYSCALL again and expect it to enter
  1814    // syscall-exit-stop for vfork() or clone(), either of which should return the
  1815    // grandchild's PID from the syscall. Aside from PTRACE_O_TRACESYSGOOD,
  1816    // syscall-stops are distinguished from signal-delivery-stop by
  1817    // PTRACE_GETSIGINFO returning a siginfo for which si_code == SIGTRAP or
  1818    // SIGTRAP|0x80.
  1819    ASSERT_THAT(ptrace(PTRACE_SYSCALL, child_pid, 0, 0), SyscallSucceeds());
  1820    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1821                SyscallSucceedsWithValue(child_pid));
  1822    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | 0x80))
  1823        << " status " << status;
  1824    ASSERT_THAT(ptrace(PTRACE_GETSIGINFO, child_pid, 0, &siginfo),
  1825                SyscallSucceeds());
  1826    EXPECT_TRUE(siginfo.si_code == SIGTRAP || siginfo.si_code == (SIGTRAP | 0x80))
  1827        << "si_code = " << siginfo.si_code;
  1828  
  1829    {
  1830      struct user_regs_struct regs = {};
  1831      struct iovec iov;
  1832      iov.iov_base = &regs;
  1833      iov.iov_len = sizeof(regs);
  1834      EXPECT_THAT(ptrace(PTRACE_GETREGSET, child_pid, NT_PRSTATUS, &iov),
  1835                  SyscallSucceeds());
  1836  #if defined(__x86_64__)
  1837      EXPECT_TRUE(regs.orig_rax == SYS_vfork || regs.orig_rax == SYS_clone)
  1838          << "orig_rax = " << regs.orig_rax;
  1839      EXPECT_EQ(grandchild_pid, regs.rax);
  1840  #elif defined(__aarch64__)
  1841      EXPECT_TRUE(regs.regs[8] == SYS_clone) << "regs[8] = " << regs.regs[8];
  1842      EXPECT_EQ(grandchild_pid, regs.regs[0]);
  1843  #endif  // defined(__x86_64__)
  1844    }
  1845  
  1846    // After this point, the child will be making wait4 syscalls that will be
  1847    // interrupted by saving, so saving is not permitted. Note that this is
  1848    // explicitly released below once the grandchild exits.
  1849    DisableSave ds;
  1850  
  1851    // Resume the child with PTRACE_SYSCALL again and expect it to enter
  1852    // syscall-enter-stop for wait4().
  1853    ASSERT_THAT(ptrace(PTRACE_SYSCALL, child_pid, 0, 0), SyscallSucceeds());
  1854    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1855                SyscallSucceedsWithValue(child_pid));
  1856    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | 0x80))
  1857        << " status " << status;
  1858    ASSERT_THAT(ptrace(PTRACE_GETSIGINFO, child_pid, 0, &siginfo),
  1859                SyscallSucceeds());
  1860    EXPECT_TRUE(siginfo.si_code == SIGTRAP || siginfo.si_code == (SIGTRAP | 0x80))
  1861        << "si_code = " << siginfo.si_code;
  1862  #ifdef __x86_64__
  1863    {
  1864      EXPECT_THAT(ptrace(PTRACE_PEEKUSER, child_pid,
  1865                         offsetof(struct user_regs_struct, orig_rax), 0),
  1866                  SyscallSucceedsWithValue(SYS_wait4));
  1867    }
  1868  #endif  // defined(__x86_64__)
  1869  
  1870    // Resume the child with PTRACE_SYSCALL again. Since the grandchild is
  1871    // waiting for the tracer (us) to acknowledge its exit first, wait4 should
  1872    // block.
  1873    ASSERT_THAT(ptrace(PTRACE_SYSCALL, child_pid, 0, 0), SyscallSucceeds());
  1874    absl::SleepFor(absl::Seconds(1));
  1875    ASSERT_THAT(waitpid(child_pid, &status, WNOHANG),
  1876                SyscallSucceedsWithValue(0));
  1877  
  1878    // Acknowledge the grandchild's exit.
  1879    ASSERT_THAT(waitpid(grandchild_pid, &status, 0),
  1880                SyscallSucceedsWithValue(grandchild_pid));
  1881    ds.reset();
  1882  
  1883    // Now the child should enter syscall-exit-stop for wait4, returning with the
  1884    // grandchild's PID.
  1885    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1886                SyscallSucceedsWithValue(child_pid));
  1887    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | 0x80))
  1888        << " status " << status;
  1889    {
  1890      struct user_regs_struct regs = {};
  1891      struct iovec iov;
  1892      iov.iov_base = &regs;
  1893      iov.iov_len = sizeof(regs);
  1894      EXPECT_THAT(ptrace(PTRACE_GETREGSET, child_pid, NT_PRSTATUS, &iov),
  1895                  SyscallSucceeds());
  1896  #if defined(__x86_64__)
  1897      EXPECT_EQ(SYS_wait4, regs.orig_rax);
  1898      EXPECT_EQ(grandchild_pid, regs.rax);
  1899  #elif defined(__aarch64__)
  1900      EXPECT_EQ(SYS_wait4, regs.regs[8]);
  1901      EXPECT_EQ(grandchild_pid, regs.regs[0]);
  1902  #endif  // defined(__x86_64__)
  1903    }
  1904  
  1905    // Detach from the child and wait for it to exit.
  1906    ASSERT_THAT(ptrace(PTRACE_DETACH, child_pid, 0, 0), SyscallSucceeds());
  1907    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1908                SyscallSucceedsWithValue(child_pid));
  1909    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
  1910        << " status " << status;
  1911  }
  1912  
  1913  // These tests requires knowledge of architecture-specific syscall convention.
  1914  #ifdef __x86_64__
  1915  TEST(PtraceTest, Int3) {
  1916    SKIP_IF(PlatformSupportInt3() == PlatformSupport::NotSupported);
  1917  
  1918    pid_t const child_pid = fork();
  1919    if (child_pid == 0) {
  1920      // In child process.
  1921  
  1922      // Enable tracing.
  1923      TEST_PCHECK(ptrace(PTRACE_TRACEME, 0, 0, 0) == 0);
  1924  
  1925      // Interrupt 3 - trap to debugger
  1926      asm("int3");
  1927  
  1928      _exit(56);
  1929    }
  1930    // In parent process.
  1931    ASSERT_THAT(child_pid, SyscallSucceeds());
  1932  
  1933    int status;
  1934    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1935                SyscallSucceedsWithValue(child_pid));
  1936    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP)
  1937        << " status " << status;
  1938  
  1939    ASSERT_THAT(ptrace(PTRACE_CONT, child_pid, 0, 0), SyscallSucceeds());
  1940  
  1941    // The child should validate the injected return value and then exit normally.
  1942    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1943                SyscallSucceedsWithValue(child_pid));
  1944    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 56)
  1945        << " status " << status;
  1946  }
  1947  
  1948  TEST(PtraceTest, Sysemu_PokeUser) {
  1949    constexpr int kSysemuHelperFirstExitCode = 126;
  1950    constexpr uint64_t kSysemuInjectedExitGroupReturn = 42;
  1951  
  1952    pid_t const child_pid = fork();
  1953    if (child_pid == 0) {
  1954      // In child process.
  1955  
  1956      // Enable tracing, then raise SIGSTOP and expect our parent to suppress it.
  1957      TEST_PCHECK(ptrace(PTRACE_TRACEME, 0, 0, 0) == 0);
  1958      RaiseSignal(SIGSTOP);
  1959  
  1960      // Try to exit_group, expecting the tracer to skip the syscall and set its
  1961      // own return value.
  1962      int const rv = syscall(SYS_exit_group, kSysemuHelperFirstExitCode);
  1963      TEST_PCHECK_MSG(rv == kSysemuInjectedExitGroupReturn,
  1964                      "exit_group returned incorrect value");
  1965  
  1966      _exit(0);
  1967    }
  1968    // In parent process.
  1969    ASSERT_THAT(child_pid, SyscallSucceeds());
  1970  
  1971    // Wait for the child to send itself SIGSTOP and enter signal-delivery-stop.
  1972    int status;
  1973    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1974                SyscallSucceedsWithValue(child_pid));
  1975    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
  1976        << " status " << status;
  1977  
  1978    // Suppress the SIGSTOP and wait for the child to enter syscall-enter-stop
  1979    // for its first exit_group syscall.
  1980    ASSERT_THAT(ptrace(kPtraceSysemu, child_pid, 0, 0), SyscallSucceeds());
  1981    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1982                SyscallSucceedsWithValue(child_pid));
  1983    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP)
  1984        << " status " << status;
  1985  
  1986    struct user_regs_struct regs = {};
  1987    ASSERT_THAT(ptrace(PTRACE_GETREGS, child_pid, 0, &regs), SyscallSucceeds());
  1988    EXPECT_EQ(SYS_exit_group, regs.orig_rax);
  1989    EXPECT_EQ(-ENOSYS, regs.rax);
  1990    EXPECT_EQ(kSysemuHelperFirstExitCode, regs.rdi);
  1991  
  1992    // Replace the exit_group return value, then resume the child, which should
  1993    // automatically skip the syscall.
  1994    ASSERT_THAT(
  1995        ptrace(PTRACE_POKEUSER, child_pid, offsetof(struct user_regs_struct, rax),
  1996               kSysemuInjectedExitGroupReturn),
  1997        SyscallSucceeds());
  1998    ASSERT_THAT(ptrace(PTRACE_DETACH, child_pid, 0, 0), SyscallSucceeds());
  1999  
  2000    // The child should validate the injected return value and then exit normally.
  2001    ASSERT_THAT(waitpid(child_pid, &status, 0),
  2002                SyscallSucceedsWithValue(child_pid));
  2003    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
  2004        << " status " << status;
  2005  }
  2006  
  2007  // This test also cares about syscall-exit-stop.
  2008  TEST(PtraceTest, ERESTART) {
  2009    constexpr int kSigno = SIGUSR1;
  2010  
  2011    pid_t const child_pid = fork();
  2012    if (child_pid == 0) {
  2013      // In child process.
  2014  
  2015      // Ignore, but unblock, kSigno.
  2016      struct sigaction sa = {};
  2017      sa.sa_handler = SIG_IGN;
  2018      TEST_PCHECK(sigfillset(&sa.sa_mask) == 0);
  2019      TEST_PCHECK(sigaction(kSigno, &sa, nullptr) == 0);
  2020      MaybeSave();
  2021      TEST_PCHECK(sigprocmask(SIG_UNBLOCK, &sa.sa_mask, nullptr) == 0);
  2022      MaybeSave();
  2023  
  2024      // Enable tracing, then raise SIGSTOP and expect our parent to suppress it.
  2025      TEST_PCHECK(ptrace(PTRACE_TRACEME, 0, 0, 0) == 0);
  2026      RaiseSignal(SIGSTOP);
  2027  
  2028      // Invoke the pause syscall, which normally should not return until we
  2029      // receive a signal that "either terminates the process or causes the
  2030      // invocation of a signal-catching function".
  2031      pause();
  2032  
  2033      _exit(0);
  2034    }
  2035    ASSERT_THAT(child_pid, SyscallSucceeds());
  2036  
  2037    // Wait for the child to send itself SIGSTOP and enter signal-delivery-stop.
  2038    int status;
  2039    ASSERT_THAT(waitpid(child_pid, &status, 0),
  2040                SyscallSucceedsWithValue(child_pid));
  2041    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
  2042        << " status " << status;
  2043  
  2044    // After this point, the child's pause syscall will be interrupted by saving,
  2045    // so saving is not permitted. Note that this is explicitly released below
  2046    // once the child is stopped.
  2047    DisableSave ds;
  2048  
  2049    // Suppress the SIGSTOP and wait for the child to enter syscall-enter-stop for
  2050    // its pause syscall.
  2051    ASSERT_THAT(ptrace(PTRACE_SYSCALL, child_pid, 0, 0), SyscallSucceeds());
  2052    ASSERT_THAT(waitpid(child_pid, &status, 0),
  2053                SyscallSucceedsWithValue(child_pid));
  2054    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP)
  2055        << " status " << status;
  2056  
  2057    struct user_regs_struct regs = {};
  2058    ASSERT_THAT(ptrace(PTRACE_GETREGS, child_pid, 0, &regs), SyscallSucceeds());
  2059    EXPECT_EQ(SYS_pause, regs.orig_rax);
  2060    EXPECT_EQ(-ENOSYS, regs.rax);
  2061  
  2062    // Resume the child with PTRACE_SYSCALL and expect it to block in the pause
  2063    // syscall.
  2064    ASSERT_THAT(ptrace(PTRACE_SYSCALL, child_pid, 0, 0), SyscallSucceeds());
  2065    absl::SleepFor(absl::Seconds(1));
  2066    ASSERT_THAT(waitpid(child_pid, &status, WNOHANG),
  2067                SyscallSucceedsWithValue(0));
  2068  
  2069    // Send the child kSigno, causing it to return ERESTARTNOHAND and enter
  2070    // syscall-exit-stop from the pause syscall.
  2071    constexpr int ERESTARTNOHAND = 514;
  2072    ASSERT_THAT(kill(child_pid, kSigno), SyscallSucceeds());
  2073    ASSERT_THAT(waitpid(child_pid, &status, 0),
  2074                SyscallSucceedsWithValue(child_pid));
  2075    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP)
  2076        << " status " << status;
  2077    ds.reset();
  2078  
  2079    ASSERT_THAT(ptrace(PTRACE_GETREGS, child_pid, 0, &regs), SyscallSucceeds());
  2080    EXPECT_EQ(SYS_pause, regs.orig_rax);
  2081    EXPECT_EQ(-ERESTARTNOHAND, regs.rax);
  2082  
  2083    // Replace the return value from pause with 0, causing pause to not be
  2084    // restarted despite kSigno being ignored.
  2085    ASSERT_THAT(ptrace(PTRACE_POKEUSER, child_pid,
  2086                       offsetof(struct user_regs_struct, rax), 0),
  2087                SyscallSucceeds());
  2088  
  2089    // Detach from the child and wait for it to exit.
  2090    ASSERT_THAT(ptrace(PTRACE_DETACH, child_pid, 0, 0), SyscallSucceeds());
  2091    ASSERT_THAT(waitpid(child_pid, &status, 0),
  2092                SyscallSucceedsWithValue(child_pid));
  2093    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
  2094        << " status " << status;
  2095  }
  2096  #endif  // defined(__x86_64__)
  2097  
  2098  TEST(PtraceTest, Seize_Interrupt_Listen) {
  2099    volatile long child_should_spin = 1;
  2100    pid_t const child_pid = fork();
  2101    if (child_pid == 0) {
  2102      // In child process.
  2103      while (child_should_spin) {
  2104        SleepSafe(absl::Seconds(1));
  2105      }
  2106      _exit(1);
  2107    }
  2108  
  2109    // In parent process.
  2110    ASSERT_THAT(child_pid, SyscallSucceeds());
  2111  
  2112    // Attach to the child with PTRACE_SEIZE; doing so should not stop the child.
  2113    ASSERT_THAT(ptrace(PTRACE_SEIZE, child_pid, 0, 0), SyscallSucceeds());
  2114    int status;
  2115    EXPECT_THAT(waitpid(child_pid, &status, WNOHANG),
  2116                SyscallSucceedsWithValue(0));
  2117  
  2118    // Stop the child with PTRACE_INTERRUPT.
  2119    ASSERT_THAT(ptrace(PTRACE_INTERRUPT, child_pid, 0, 0), SyscallSucceeds());
  2120    ASSERT_THAT(waitpid(child_pid, &status, 0),
  2121                SyscallSucceedsWithValue(child_pid));
  2122    EXPECT_EQ(SIGTRAP | (kPtraceEventStop << 8), status >> 8);
  2123  
  2124    // Unset child_should_spin to verify that the child never leaves the spin
  2125    // loop.
  2126    ASSERT_THAT(ptrace(PTRACE_POKEDATA, child_pid, &child_should_spin, 0),
  2127                SyscallSucceeds());
  2128  
  2129    // Send SIGSTOP to the child, then resume it, allowing it to proceed to
  2130    // signal-delivery-stop.
  2131    ASSERT_THAT(kill(child_pid, SIGSTOP), SyscallSucceeds());
  2132    ASSERT_THAT(ptrace(PTRACE_CONT, child_pid, 0, 0), SyscallSucceeds());
  2133    ASSERT_THAT(waitpid(child_pid, &status, 0),
  2134                SyscallSucceedsWithValue(child_pid));
  2135    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
  2136        << " status " << status;
  2137  
  2138    // Release the child from signal-delivery-stop without suppressing the
  2139    // SIGSTOP, causing it to enter group-stop.
  2140    ASSERT_THAT(ptrace(PTRACE_CONT, child_pid, 0, SIGSTOP), SyscallSucceeds());
  2141    ASSERT_THAT(waitpid(child_pid, &status, 0),
  2142                SyscallSucceedsWithValue(child_pid));
  2143    EXPECT_EQ(SIGSTOP | (kPtraceEventStop << 8), status >> 8);
  2144  
  2145    // "The state of the tracee after PTRACE_LISTEN is somewhat of a gray area: it
  2146    // is not in any ptrace-stop (ptrace commands won't work on it, and it will
  2147    // deliver waitpid(2) notifications), but it also may be considered 'stopped'
  2148    // because it is not executing instructions (is not scheduled), and if it was
  2149    // in group-stop before PTRACE_LISTEN, it will not respond to signals until
  2150    // SIGCONT is received." - ptrace(2).
  2151    ASSERT_THAT(ptrace(PTRACE_LISTEN, child_pid, 0, 0), SyscallSucceeds());
  2152    EXPECT_THAT(ptrace(PTRACE_CONT, child_pid, 0, 0),
  2153                SyscallFailsWithErrno(ESRCH));
  2154    EXPECT_THAT(waitpid(child_pid, &status, WNOHANG),
  2155                SyscallSucceedsWithValue(0));
  2156    EXPECT_THAT(kill(child_pid, SIGTERM), SyscallSucceeds());
  2157    absl::SleepFor(absl::Seconds(1));
  2158    EXPECT_THAT(waitpid(child_pid, &status, WNOHANG),
  2159                SyscallSucceedsWithValue(0));
  2160  
  2161    // Send SIGCONT to the child, causing it to leave group-stop and re-trap due
  2162    // to PTRACE_LISTEN.
  2163    EXPECT_THAT(kill(child_pid, SIGCONT), SyscallSucceeds());
  2164    ASSERT_THAT(waitpid(child_pid, &status, 0),
  2165                SyscallSucceedsWithValue(child_pid));
  2166    EXPECT_EQ(SIGTRAP | (kPtraceEventStop << 8), status >> 8);
  2167  
  2168    // Detach the child and expect it to exit due to the SIGTERM we sent while
  2169    // it was stopped by PTRACE_LISTEN.
  2170    ASSERT_THAT(ptrace(PTRACE_DETACH, child_pid, 0, 0), SyscallSucceeds());
  2171    ASSERT_THAT(waitpid(child_pid, &status, 0),
  2172                SyscallSucceedsWithValue(child_pid));
  2173    EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM)
  2174        << " status " << status;
  2175  }
  2176  
  2177  TEST(PtraceTest, Interrupt_Listen_RequireSeize) {
  2178    pid_t const child_pid = fork();
  2179    if (child_pid == 0) {
  2180      // In child process.
  2181      TEST_PCHECK(ptrace(PTRACE_TRACEME, 0, 0, 0) == 0);
  2182      MaybeSave();
  2183      raise(SIGSTOP);
  2184      _exit(0);
  2185    }
  2186    // In parent process.
  2187    ASSERT_THAT(child_pid, SyscallSucceeds());
  2188  
  2189    // Wait for the child to send itself SIGSTOP and enter signal-delivery-stop.
  2190    int status;
  2191    ASSERT_THAT(waitpid(child_pid, &status, 0),
  2192                SyscallSucceedsWithValue(child_pid));
  2193    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
  2194        << " status " << status;
  2195  
  2196    // PTRACE_INTERRUPT and PTRACE_LISTEN should fail since the child wasn't
  2197    // attached with PTRACE_SEIZE, leaving the child in signal-delivery-stop.
  2198    EXPECT_THAT(ptrace(PTRACE_INTERRUPT, child_pid, 0, 0),
  2199                SyscallFailsWithErrno(EIO));
  2200    EXPECT_THAT(ptrace(PTRACE_LISTEN, child_pid, 0, 0),
  2201                SyscallFailsWithErrno(EIO));
  2202  
  2203    // Suppress SIGSTOP and detach from the child, expecting it to exit normally.
  2204    ASSERT_THAT(ptrace(PTRACE_DETACH, child_pid, 0, 0), SyscallSucceeds());
  2205    ASSERT_THAT(waitpid(child_pid, &status, 0),
  2206                SyscallSucceedsWithValue(child_pid));
  2207    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
  2208        << " status " << status;
  2209  }
  2210  
  2211  TEST(PtraceTest, SeizeSetOptions) {
  2212    pid_t const child_pid = fork();
  2213    if (child_pid == 0) {
  2214      // In child process.
  2215      while (true) {
  2216        SleepSafe(absl::Seconds(1));
  2217      }
  2218    }
  2219  
  2220    // In parent process.
  2221    ASSERT_THAT(child_pid, SyscallSucceeds());
  2222  
  2223    // Attach to the child with PTRACE_SEIZE while setting PTRACE_O_TRACESYSGOOD.
  2224    ASSERT_THAT(ptrace(PTRACE_SEIZE, child_pid, 0, PTRACE_O_TRACESYSGOOD),
  2225                SyscallSucceeds());
  2226  
  2227    // Stop the child with PTRACE_INTERRUPT.
  2228    ASSERT_THAT(ptrace(PTRACE_INTERRUPT, child_pid, 0, 0), SyscallSucceeds());
  2229    int status;
  2230    ASSERT_THAT(waitpid(child_pid, &status, 0),
  2231                SyscallSucceedsWithValue(child_pid));
  2232    EXPECT_EQ(SIGTRAP | (kPtraceEventStop << 8), status >> 8);
  2233  
  2234    // Resume the child with PTRACE_SYSCALL and wait for it to enter
  2235    // syscall-enter-stop. The stop signal status from the syscall stop should be
  2236    // SIGTRAP|0x80, reflecting PTRACE_O_TRACESYSGOOD.
  2237    ASSERT_THAT(ptrace(PTRACE_SYSCALL, child_pid, 0, 0), SyscallSucceeds());
  2238    ASSERT_THAT(waitpid(child_pid, &status, 0),
  2239                SyscallSucceedsWithValue(child_pid));
  2240    EXPECT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | 0x80))
  2241        << " status " << status;
  2242  
  2243    // Clean up the child.
  2244    ASSERT_THAT(kill(child_pid, SIGKILL), SyscallSucceeds());
  2245    ASSERT_THAT(waitpid(child_pid, &status, 0),
  2246                SyscallSucceedsWithValue(child_pid));
  2247    if (WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | 0x80)) {
  2248      // "SIGKILL kills even within system calls (syscall-exit-stop is not
  2249      // generated prior to death by SIGKILL). The net effect is that SIGKILL
  2250      // always kills the process (all its threads), even if some threads of the
  2251      // process are ptraced." - ptrace(2). This is technically true, but...
  2252      //
  2253      // When we send SIGKILL to the child, kernel/signal.c:complete_signal() =>
  2254      // signal_wake_up(resume=1) kicks the tracee out of the syscall-enter-stop.
  2255      // The pending SIGKILL causes the syscall to be skipped, but the child
  2256      // thread still reports syscall-exit before checking for pending signals; in
  2257      // current kernels, this is
  2258      // arch/x86/entry/common.c:syscall_return_slowpath() =>
  2259      // syscall_slow_exit_work() =>
  2260      // include/linux/tracehook.h:tracehook_report_syscall_exit() =>
  2261      // ptrace_report_syscall() => kernel/signal.c:ptrace_notify() =>
  2262      // ptrace_do_notify() => ptrace_stop().
  2263      //
  2264      // ptrace_stop() sets the task's state to TASK_TRACED and the task's
  2265      // exit_code to SIGTRAP|0x80 (passed by ptrace_report_syscall()), then calls
  2266      // freezable_schedule(). freezable_schedule() eventually reaches
  2267      // __schedule(), which detects signal_pending_state() due to the pending
  2268      // SIGKILL, sets the task's state back to TASK_RUNNING, and returns without
  2269      // descheduling. Thus, the task never enters syscall-exit-stop. However, if
  2270      // our wait4() => kernel/exit.c:wait_task_stopped() racily observes the
  2271      // TASK_TRACED state and the non-zero exit code set by ptrace_stop() before
  2272      // __schedule() sets the state back to TASK_RUNNING, it will return the
  2273      // task's exit_code as status W_STOPCODE(SIGTRAP|0x80). So we get a spurious
  2274      // syscall-exit-stop notification, and need to wait4() again for task exit.
  2275      //
  2276      // gVisor is not susceptible to this race because
  2277      // kernel.Task.waitCollectTraceeStopLocked() checks specifically for an
  2278      // active ptraceStop, which is not initiated if SIGKILL is pending.
  2279      std::cout << "Observed syscall-exit after SIGKILL" << std::endl;
  2280      ASSERT_THAT(waitpid(child_pid, &status, 0),
  2281                  SyscallSucceedsWithValue(child_pid));
  2282    }
  2283    EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
  2284        << " status " << status;
  2285  }
  2286  
  2287  TEST(PtraceTest, SetYAMAPtraceScope) {
  2288    // Do not modify the ptrace scope on the host.
  2289    SKIP_IF(!IsRunningOnGvisor());
  2290    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));
  2291  
  2292    const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(
  2293        Open(std::string(kYamaPtraceScopePath), O_RDWR));
  2294  
  2295    ASSERT_THAT(write(fd.get(), "0", 1), SyscallSucceedsWithValue(1));
  2296  
  2297    ASSERT_THAT(lseek(fd.get(), 0, SEEK_SET), SyscallSucceeds());
  2298    std::vector<char> buf(10);
  2299    EXPECT_THAT(read(fd.get(), buf.data(), buf.size()), SyscallSucceeds());
  2300    EXPECT_STREQ(buf.data(), "0\n");
  2301  
  2302    // Test that a child can attach to its parent when ptrace_scope is 0.
  2303    AutoCapability cap(CAP_SYS_PTRACE, false);
  2304    pid_t const child_pid = fork();
  2305    if (child_pid == 0) {
  2306      TEST_PCHECK(CheckPtraceAttach(getppid()) == 0);
  2307      _exit(0);
  2308    }
  2309    ASSERT_THAT(child_pid, SyscallSucceeds());
  2310  
  2311    int status;
  2312    ASSERT_THAT(waitpid(child_pid, &status, 0), SyscallSucceeds());
  2313    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
  2314        << " status " << status;
  2315  
  2316    // Set ptrace_scope back to 1 (and try writing with a newline).
  2317    ASSERT_THAT(lseek(fd.get(), 0, SEEK_SET), SyscallSucceeds());
  2318    ASSERT_THAT(write(fd.get(), "1\n", 2), SyscallSucceedsWithValue(2));
  2319  
  2320    ASSERT_THAT(lseek(fd.get(), 0, SEEK_SET), SyscallSucceeds());
  2321    EXPECT_THAT(read(fd.get(), buf.data(), buf.size()), SyscallSucceeds());
  2322    EXPECT_STREQ(buf.data(), "1\n");
  2323  }
  2324  
  2325  }  // namespace
  2326  
  2327  }  // namespace testing
  2328  }  // namespace gvisor
  2329  
  2330  int main(int argc, char** argv) {
  2331    gvisor::testing::TestInit(&argc, &argv);
  2332  
  2333    if (absl::GetFlag(FLAGS_ptrace_test_execve_child)) {
  2334      gvisor::testing::RunExecveChild();
  2335    }
  2336  
  2337    int fd = absl::GetFlag(FLAGS_ptrace_test_fd);
  2338  
  2339    if (absl::GetFlag(FLAGS_ptrace_test_trace_descendants_allowed)) {
  2340      gvisor::testing::RunTraceDescendantsAllowed(fd);
  2341    }
  2342  
  2343    if (absl::GetFlag(FLAGS_ptrace_test_ptrace_attacher)) {
  2344      gvisor::testing::RunPtraceAttacher(fd);
  2345    }
  2346  
  2347    if (absl::GetFlag(FLAGS_ptrace_test_prctl_set_ptracer)) {
  2348      gvisor::testing::RunPrctlSetPtracer(fd);
  2349    }
  2350  
  2351    if (absl::GetFlag(
  2352            FLAGS_ptrace_test_prctl_set_ptracer_and_exit_tracee_thread)) {
  2353      gvisor::testing::RunPrctlSetPtracerPersistsPastTraceeThreadExit(fd);
  2354    }
  2355  
  2356    if (absl::GetFlag(FLAGS_ptrace_test_prctl_set_ptracer_and_exec_non_leader)) {
  2357      gvisor::testing::RunPrctlSetPtracerDoesNotPersistPastNonLeaderExec(
  2358          fd);
  2359    }
  2360  
  2361    if (absl::GetFlag(
  2362            FLAGS_ptrace_test_prctl_set_ptracer_and_exit_tracer_thread)) {
  2363      gvisor::testing::RunPrctlSetPtracerDoesNotPersistPastTracerThreadExit(
  2364          absl::GetFlag(
  2365              FLAGS_ptrace_test_prctl_set_ptracer_and_exit_tracer_thread_tid),
  2366          fd);
  2367    }
  2368  
  2369    if (absl::GetFlag(
  2370            FLAGS_ptrace_test_prctl_set_ptracer_respects_tracer_thread_id)) {
  2371      gvisor::testing::RunPrctlSetPtracerRespectsTracerThreadID(
  2372          absl::GetFlag(
  2373              FLAGS_ptrace_test_prctl_set_ptracer_respects_tracer_thread_id_tid),
  2374          fd);
  2375    }
  2376  
  2377    if (absl::GetFlag(FLAGS_ptrace_test_tracee)) {
  2378      gvisor::testing::RunTracee(fd);
  2379    }
  2380  
  2381    int pid = absl::GetFlag(FLAGS_ptrace_test_trace_tid);
  2382    if (pid != -1) {
  2383      gvisor::testing::RunTraceTID(pid, fd);
  2384    }
  2385  
  2386    return gvisor::testing::RunAllTests();
  2387  }