xref: /aosp_15_r20/external/sandboxed-api/sandboxed_api/sandbox2/monitor_ptrace.h (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1 // Copyright 2023 Google LLC
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 //     https://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 // The sandbox2::Monitor class is responsible for tracking the processes, and
16 // displaying their current statuses (syscalls, states, violations).
17 
18 #ifndef SANDBOXED_API_SANDBOX2_MONITOR_PTRACE_H_
19 #define SANDBOXED_API_SANDBOX2_MONITOR_PTRACE_H_
20 
21 #include <atomic>
22 #include <cstdint>
23 #include <memory>
24 #include <thread>
25 
26 #include "absl/container/flat_hash_map.h"
27 #include "absl/log/log.h"
28 #include "absl/synchronization/mutex.h"
29 #include "absl/synchronization/notification.h"
30 #include "absl/time/clock.h"
31 #include "absl/time/time.h"
32 #include "sandboxed_api/sandbox2/executor.h"
33 #include "sandboxed_api/sandbox2/monitor_base.h"
34 #include "sandboxed_api/sandbox2/notify.h"
35 #include "sandboxed_api/sandbox2/policy.h"
36 #include "sandboxed_api/sandbox2/regs.h"
37 #include "sandboxed_api/sandbox2/syscall.h"
38 #include "sandboxed_api/util/raw_logging.h"
39 
40 namespace sandbox2 {
41 
42 class PtraceMonitor : public MonitorBase {
43  public:
44   PtraceMonitor(Executor* executor, Policy* policy, Notify* notify);
~PtraceMonitor()45   ~PtraceMonitor() { Join(); }
46 
Kill()47   void Kill() override {
48     external_kill_request_flag_.clear(std::memory_order_relaxed);
49     NotifyMonitor();
50   }
51 
DumpStackTrace()52   void DumpStackTrace() override {
53     dump_stack_request_flag_.clear(std::memory_order_relaxed);
54     NotifyMonitor();
55   }
56 
SetWallTimeLimit(absl::Duration limit)57   void SetWallTimeLimit(absl::Duration limit) override {
58     if (limit == absl::ZeroDuration()) {
59       VLOG(1) << "Disarming walltime timer to ";
60       deadline_millis_.store(0, std::memory_order_relaxed);
61     } else {
62       VLOG(1) << "Will set the walltime timer to " << limit;
63       absl::Time deadline = absl::Now() + limit;
64       deadline_millis_.store(absl::ToUnixMillis(deadline),
65                              std::memory_order_relaxed);
66     }
67   }
68 
69  private:
70   // Timeout used with sigtimedwait (0.5s).
71   static constexpr int kWakeUpPeriodSec = 0L;
72   static constexpr int kWakeUpPeriodNSec = (500L * 1000L * 1000L);
73 
74   // Waits for events from monitored clients and signals from the main process.
75   void RunInternal() override;
76   void Join() override;
77   void Run();
78 
79   // Notifies monitor about a state change
80   void NotifyMonitor();
81 
82   // PID called a traced syscall, or was killed due to syscall.
83   void ActionProcessSyscall(Regs* regs, const Syscall& syscall);
84 
85   // Getter/Setter for wait_for_execve_.
86   bool IsActivelyMonitoring();
87   void SetActivelyMonitoring();
88 
89   // Process with given PID changed state to a stopped state.
90   void StateProcessStopped(pid_t pid, int status);
91 
92   // Sets additional information in the result object, such as program name,
93   // stack trace etc.
94   void SetAdditionalResultInfo(std::unique_ptr<Regs> regs);
95 
96   // Logs the syscall violation and kills the process afterwards.
97   void ActionProcessSyscallViolation(Regs* regs, const Syscall& syscall,
98                                      ViolationType violation_type);
99 
100   void LogStackTraceOfPid(pid_t pid);
101 
102   // Ptrace events:
103   // Syscall violation processing path.
104   void EventPtraceSeccomp(pid_t pid, int event_msg);
105 
106   // Processes exit path.
107   void EventPtraceExit(pid_t pid, int event_msg);
108 
109   // Processes fork/vfork/clone path.
110   void EventPtraceNewProcess(pid_t pid, int event_msg);
111 
112   // Processes execution path.
113   void EventPtraceExec(pid_t pid, int event_msg);
114 
115   // Processes stop path.
116   void EventPtraceStop(pid_t pid, int stopsig);
117 
118   // Processes syscall exit.
119   void EventSyscallExit(pid_t pid);
120 
121   // Kills the main traced PID with PTRACE_KILL.
122   // Returns false if an error occured and process could not be killed.
123   bool KillSandboxee();
124 
125   // Interrupts the main traced PID with PTRACE_INTERRUPT.
126   // Returns false if an error occured and process could not be interrupted.
127   bool InterruptSandboxee();
128 
129   // Sets up required signal masks/handlers; prepare mask for sigtimedwait().
130   bool InitSetupSignals();
131 
132   // ptrace(PTRACE_SEIZE) to the Client.
133   // Returns success/failure status.
134   bool InitPtraceAttach();
135 
136   // Parent (the Sandbox2 object) waits on it, until we either enable
137   // monitoring of a process (sandboxee) successfully, or the setup process
138   // fails.
139   absl::Notification setup_notification_;
140   // Deadline in Unix millis
141   std::atomic<int64_t> deadline_millis_{0};
142   // False iff external kill is requested
143   std::atomic_flag external_kill_request_flag_ = ATOMIC_FLAG_INIT;
144   // False iff dump stack is requested
145   std::atomic_flag dump_stack_request_flag_ = ATOMIC_FLAG_INIT;
146   // Was external kill sent to the sandboxee
147   bool external_kill_ = false;
148   // Network violation occurred and process of killing sandboxee started
149   bool network_violation_ = false;
150   // Is the sandboxee timed out
151   bool timed_out_ = false;
152   // Should we dump the main sandboxed PID's stack?
153   bool should_dump_stack_ = false;
154   // Is the sandboxee actively monitored, or maybe we're waiting for execve()?
155   bool wait_for_execve_;
156   // Syscalls that are running, whose result values we want to inspect.
157   absl::flat_hash_map<pid_t, Syscall> syscalls_in_progress_;
158   sigset_t sset_;
159   // Deadline after which sandboxee get terminated via PTRACE_O_EXITKILL.
160   absl::Time hard_deadline_ = absl::InfiniteFuture();
161 
162   // Monitor thread object.
163   std::unique_ptr<std::thread> thread_;
164 
165   // Synchronizes monitor thread deletion and notifying the monitor.
166   absl::Mutex notify_mutex_;
167 };
168 
169 }  // namespace sandbox2
170 
171 #endif  // SANDBOXED_API_SANDBOX2_MONITOR_BASE_H_
172