1 #ifndef SANDBOXED_API_SANDBOX2_MONITOR_UNOTIFY_H_ 2 #define SANDBOXED_API_SANDBOX2_MONITOR_UNOTIFY_H_ 3 4 #include <linux/seccomp.h> 5 #include <sys/sysinfo.h> 6 #include <sys/types.h> 7 8 #include <atomic> 9 #include <cstdint> 10 #include <cstdlib> 11 #include <memory> 12 #include <thread> 13 #include <string> 14 #include <vector> 15 16 #include "absl/log/log.h" 17 #include "absl/status/statusor.h" 18 #include "absl/synchronization/mutex.h" 19 #include "absl/synchronization/notification.h" 20 #include "absl/time/clock.h" 21 #include "absl/time/time.h" 22 #include "sandboxed_api/sandbox2/executor.h" 23 #include "sandboxed_api/sandbox2/monitor_base.h" 24 #include "sandboxed_api/sandbox2/notify.h" 25 #include "sandboxed_api/sandbox2/policy.h" 26 #include "sandboxed_api/sandbox2/result.h" 27 #include "sandboxed_api/util/fileops.h" 28 #include "sandboxed_api/util/raw_logging.h" 29 30 namespace sandbox2 { 31 32 #ifndef SECCOMP_IOCTL_NOTIF_RECV 33 struct seccomp_notif { 34 __u64 id; 35 __u32 pid; 36 __u32 flags; 37 struct seccomp_data data; 38 }; 39 #endif 40 41 class UnotifyMonitor : public MonitorBase { 42 public: 43 UnotifyMonitor(Executor* executor, Policy* policy, Notify* notify); ~UnotifyMonitor()44 ~UnotifyMonitor() { Join(); } 45 Kill()46 void Kill() override { 47 external_kill_request_flag_.clear(std::memory_order_relaxed); 48 NotifyMonitor(); 49 } 50 DumpStackTrace()51 void DumpStackTrace() override { 52 dump_stack_request_flag_.clear(std::memory_order_relaxed); 53 NotifyMonitor(); 54 } 55 SetWallTimeLimit(absl::Duration limit)56 void SetWallTimeLimit(absl::Duration limit) override { 57 if (limit == absl::ZeroDuration()) { 58 VLOG(1) << "Disarming walltime timer to "; 59 deadline_millis_.store(0, std::memory_order_relaxed); 60 } else { 61 VLOG(1) << "Will set the walltime timer to " << limit; 62 absl::Time deadline = absl::Now() + limit; 63 deadline_millis_.store(absl::ToUnixMillis(deadline), 64 std::memory_order_relaxed); 65 NotifyMonitor(); 66 } 67 } 68 69 private: 70 // Waits for events from monitored clients and signals from the main process. 71 void RunInternal() override; 72 void Join() override; 73 void Run(); 74 75 bool InitSetupUnotify(); 76 bool InitSetupNotifyEventFd(); 77 // Kills the main traced PID with SIGKILL. 78 // Returns false if an error occured and process could not be killed. 79 bool KillSandboxee(); 80 void KillInit(); 81 82 void HandleUnotify(); 83 void SetExitStatusFromStatusPipe(); 84 85 void MaybeGetStackTrace(pid_t pid, Result::StatusEnum status); 86 absl::StatusOr<std::vector<std::string>> GetStackTrace(pid_t pid); 87 88 // Notifies monitor about a state change 89 void NotifyMonitor(); 90 91 absl::Notification setup_notification_; 92 sapi::file_util::fileops::FDCloser seccomp_notify_fd_; 93 sapi::file_util::fileops::FDCloser monitor_notify_fd_; 94 // Deadline in Unix millis 95 std::atomic<int64_t> deadline_millis_{0}; 96 // False iff external kill is requested 97 std::atomic_flag external_kill_request_flag_ = ATOMIC_FLAG_INIT; 98 // False iff dump stack is requested 99 std::atomic_flag dump_stack_request_flag_ = ATOMIC_FLAG_INIT; 100 101 // Was external kill sent to the sandboxee 102 bool external_kill_ = false; 103 // Network violation occurred and process of killing sandboxee started 104 bool network_violation_ = false; 105 // Is the sandboxee timed out 106 bool timed_out_ = false; 107 108 // Monitor thread object. 109 std::unique_ptr<std::thread> thread_; 110 111 // Synchronizes monitor thread deletion and notifying the monitor. 112 absl::Mutex notify_mutex_; 113 114 size_t req_size_; 115 std::unique_ptr<seccomp_notif, decltype(std::free)*> req_{nullptr, std::free}; 116 }; 117 118 } // namespace sandbox2 119 120 #endif // SANDBOXED_API_SANDBOX2_MONITOR_UNOTIFY_H_ 121