• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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