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