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