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