@@ -72,6 +72,10 @@ ABSL_FLAG(bool, sandbox2_log_all_stack_traces, false,
7272 " If set, sandbox2 monitor will log stack traces of all monitored "
7373 " threads/processes that are reported to terminate with a signal." );
7474
75+ ABSL_FLAG (bool , sandbox2_monitor_ptrace_use_deadline_manager, false ,
76+ " If set, ptrace monitor will use deadline manager to enforce "
77+ " deadlines and as notification mechanism." );
78+
7579ABSL_FLAG (bool , sandbox2_log_unobtainable_stack_traces_errors, true ,
7680 " If set, unobtainable stack trace will be logged as errors." );
7781
@@ -143,6 +147,8 @@ PtraceMonitor::PtraceMonitor(Executor* executor, Policy* policy, Notify* notify)
143147 }
144148 external_kill_request_flag_.test_and_set (std::memory_order_relaxed);
145149 dump_stack_request_flag_.test_and_set (std::memory_order_relaxed);
150+ use_deadline_manager_ =
151+ absl::GetFlag (FLAGS_sandbox2_monitor_ptrace_use_deadline_manager);
146152}
147153
148154bool PtraceMonitor::IsActivelyMonitoring () {
@@ -200,14 +206,18 @@ bool PtraceMonitor::InterruptSandboxee() {
200206#define __WPTRACEEVENT (x ) ((x & 0xff0000 ) >> 16 )
201207
202208void PtraceMonitor::NotifyMonitor () {
203- absl::ReaderMutexLock lock (¬ify_mutex_);
204- if (thread_.IsJoinable ()) {
205- pthread_kill (thread_.handle (), SIGCHLD);
209+ if (use_deadline_manager_) {
210+ pid_waiter_.Notify ();
211+ } else {
212+ absl::MutexLock lock (&thread_mutex_);
213+ if (thread_.IsJoinable ()) {
214+ pthread_kill (thread_.handle (), SIGCHLD);
215+ }
206216 }
207217}
208218
209219void PtraceMonitor::Join () {
210- absl::MutexLock lock (¬ify_mutex_ );
220+ absl::MutexLock lock (&thread_mutex_ );
211221 if (thread_.IsJoinable ()) {
212222 thread_.Join ();
213223 CHECK (IsDone ()) << " Monitor did not terminate" ;
@@ -217,7 +227,10 @@ void PtraceMonitor::Join() {
217227}
218228
219229void PtraceMonitor::RunInternal () {
220- thread_ = sapi::Thread (this , &PtraceMonitor::Run, " sandbox2-Monitor" );
230+ {
231+ absl::MutexLock lock (&thread_mutex_);
232+ thread_ = sapi::Thread (this , &PtraceMonitor::Run, " sandbox2-Monitor" );
233+ }
221234
222235 // Wait for the Monitor to set-up the sandboxee correctly (or fail while
223236 // doing that). From here on, it is safe to use the IPC object for
@@ -234,7 +247,7 @@ void PtraceMonitor::Run() {
234247 absl::Cleanup setup_notify = [this ] { setup_notification_.Notify (); };
235248 // It'd be costly to initialize the sigset_t for each sigtimedwait()
236249 // invocation, so do it once per Monitor.
237- if (!InitSetupSignals ()) {
250+ if (!use_deadline_manager_ && ! InitSetupSignals ()) {
238251 SetExitStatusCode (Result::SETUP_ERROR, Result::FAILED_SIGNALS);
239252 return ;
240253 }
@@ -251,7 +264,7 @@ void PtraceMonitor::Run() {
251264 std::move (setup_notify).Invoke ();
252265
253266 bool sandboxee_exited = false ;
254- PidWaiter pid_waiter (process_.main_pid );
267+ pid_waiter_. SetPriorityPid (process_.main_pid );
255268 int status;
256269 // All possible still running children of main process, will be killed due to
257270 // PTRACE_O_EXITKILL ptrace() flag.
@@ -295,13 +308,21 @@ void PtraceMonitor::Run() {
295308 break ;
296309 }
297310 }
298-
299- pid_t ret = pid_waiter.Wait (&status);
311+ if (use_deadline_manager_) {
312+ absl::Time effective_deadline = hard_deadline_;
313+ if (deadline != 0 && hard_deadline_ == absl::InfiniteFuture ()) {
314+ effective_deadline = absl::FromUnixMillis (deadline);
315+ }
316+ pid_waiter_.SetDeadline (effective_deadline);
317+ }
318+ pid_t ret = pid_waiter_.Wait (&status);
300319 if (ret == 0 ) {
301- constexpr timespec ts = {kWakeUpPeriodSec , kWakeUpPeriodNSec };
302- int signo = sigtimedwait (&sset_, nullptr , &ts);
303- LOG_IF (ERROR, signo != -1 && signo != SIGCHLD)
304- << " Unknown signal received: " << signo;
320+ if (!use_deadline_manager_) {
321+ constexpr timespec ts = {kWakeUpPeriodSec , kWakeUpPeriodNSec };
322+ int signo = sigtimedwait (&sset_, nullptr , &ts);
323+ LOG_IF (ERROR, signo != -1 && signo != SIGCHLD)
324+ << " Unknown signal received: " << signo;
325+ }
305326 continue ;
306327 }
307328
@@ -310,7 +331,7 @@ void PtraceMonitor::Run() {
310331 LOG (ERROR) << " PANIC(). The main process has not exited yet, "
311332 << " yet we haven't seen its exit event" ;
312333 SetExitStatusCode (Result::INTERNAL_ERROR, Result::FAILED_CHILD);
313- } else {
334+ } else if (!use_deadline_manager_ || errno != EINTR) {
314335 PLOG (ERROR) << " waitpid() failed" ;
315336 }
316337 continue ;
@@ -381,8 +402,14 @@ void PtraceMonitor::Run() {
381402 << result_.ToString ();
382403 break ;
383404 }
384- pid_t ret = pid_waiter.Wait (&status);
405+ if (use_deadline_manager_) {
406+ pid_waiter_.SetDeadline (deadline);
407+ }
408+ pid_t ret = pid_waiter_.Wait (&status);
385409 if (ret == -1 ) {
410+ if (use_deadline_manager_ && errno == EINTR) {
411+ continue ;
412+ }
386413 if (!log_stack_traces || ret != ECHILD) {
387414 PLOG (ERROR) << " waitpid() failed" ;
388415 }
@@ -397,8 +424,10 @@ void PtraceMonitor::Run() {
397424 }
398425
399426 if (ret == 0 ) {
400- auto ts = absl::ToTimespec (left);
401- sigtimedwait (&sset_, nullptr , &ts);
427+ if (!use_deadline_manager_) {
428+ auto ts = absl::ToTimespec (left);
429+ sigtimedwait (&sset_, nullptr , &ts);
430+ }
402431 continue ;
403432 }
404433
0 commit comments