1 // Copyright 2019 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::Sandbox object is the central object of the Sandbox2. 16 // It handles sandboxed jobs. 17 18 #ifndef SANDBOXED_API_SANDBOX2_SANDBOX2_H_ 19 #define SANDBOXED_API_SANDBOX2_SANDBOX2_H_ 20 21 #include <ctime> 22 #include <memory> 23 #include <utility> 24 25 #include "absl/base/attributes.h" 26 #include "absl/base/macros.h" 27 #include "absl/log/check.h" 28 #include "absl/status/status.h" 29 #include "absl/status/statusor.h" 30 #include "absl/time/time.h" 31 #include "sandboxed_api/sandbox2/comms.h" 32 #include "sandboxed_api/sandbox2/executor.h" 33 #include "sandboxed_api/sandbox2/ipc.h" 34 #include "sandboxed_api/sandbox2/monitor_base.h" 35 #include "sandboxed_api/sandbox2/notify.h" 36 #include "sandboxed_api/sandbox2/policy.h" 37 #include "sandboxed_api/sandbox2/result.h" 38 39 namespace sandbox2 { 40 41 class Sandbox2 final { 42 public: Sandbox2(std::unique_ptr<Executor> executor,std::unique_ptr<Policy> policy)43 Sandbox2(std::unique_ptr<Executor> executor, std::unique_ptr<Policy> policy) 44 : Sandbox2(std::move(executor), std::move(policy), /*notify=*/nullptr) {} 45 Sandbox2(std::unique_ptr<Executor> executor,std::unique_ptr<Policy> policy,std::unique_ptr<Notify> notify)46 Sandbox2(std::unique_ptr<Executor> executor, std::unique_ptr<Policy> policy, 47 std::unique_ptr<Notify> notify) 48 : executor_(std::move(executor)), 49 policy_(std::move(policy)), 50 notify_(std::move(notify)) { 51 CHECK(executor_ != nullptr); 52 CHECK(policy_ != nullptr); 53 } 54 55 Sandbox2(const Sandbox2&) = delete; 56 Sandbox2& operator=(const Sandbox2&) = delete; 57 58 // Runs the sandbox, blocking until there is a result. Run()59 ABSL_MUST_USE_RESULT Result Run() { 60 RunAsync(); 61 return AwaitResult(); 62 } 63 64 // Runs asynchronously. The return value indicates whether the sandboxee 65 // set-up process succeeded 66 // Even if set-up fails AwaitResult can still used to get a more specific 67 // failure reason. 68 bool RunAsync(); 69 // Waits for sandbox execution to finish and returns the execution result. 70 ABSL_MUST_USE_RESULT Result AwaitResult(); 71 72 // Waits for sandbox execution to finish within the timeout. 73 // Returns execution result or a DeadlineExceededError if the sandboxee does 74 // not finish in time. 75 absl::StatusOr<Result> AwaitResultWithTimeout(absl::Duration timeout); 76 77 // Requests termination of the sandboxee. 78 // Sandbox should still waited with AwaitResult(), as it may finish for other 79 // reason before the request is handled. 80 void Kill(); 81 82 // Dumps the main sandboxed process's stack trace to log. 83 void DumpStackTrace(); 84 85 // Returns whether sandboxing task has ended. 86 bool IsTerminated() const; 87 88 // Sets a wall time limit on a running sandboxee, 0 to disarm. 89 // Limit is a timeout duration (e.g. 10 secs) not a deadline (e.g. 12:00). 90 // This can be useful in a persistent sandbox scenario, to impose a deadline 91 // for responses after each request and reset the deadline in between. 92 // Sandboxed API can be used to implement persistent sandboxes. 93 ABSL_DEPRECATED("Use set_walltime_limit() instead") SetWallTimeLimit(time_t limit)94 void SetWallTimeLimit(time_t limit) const { 95 this->set_walltime_limit(absl::Seconds(limit)); 96 } 97 98 // Sets a wall time limit on a running sandboxee, absl::ZeroDuration() to 99 // disarm. This can be useful in a persistent sandbox scenario, to impose a 100 // deadline for responses after each request and reset the deadline in 101 // between. Sandboxed API can be used to implement persistent sandboxes. 102 void set_walltime_limit(absl::Duration limit) const; 103 104 // Returns the process id inside the executor. pid()105 pid_t pid() const { return monitor_ != nullptr ? monitor_->pid() : -1; } 106 107 // Gets the comms inside the executor. comms()108 Comms* comms() { 109 return executor_ != nullptr ? executor_->ipc()->comms() : nullptr; 110 } 111 112 absl::Status EnableUnotifyMonitor(); 113 114 private: 115 // Launches the Monitor. 116 void Launch(); 117 118 std::unique_ptr<MonitorBase> CreateMonitor(); 119 120 // Executor set by user - owned by Sandbox2. 121 std::unique_ptr<Executor> executor_; 122 123 // Seccomp policy set by the user - owned by Sandbox2. 124 std::unique_ptr<Policy> policy_; 125 126 // Notify object - owned by Sandbox2. 127 std::unique_ptr<Notify> notify_; 128 129 // Monitor object - owned by Sandbox2. 130 std::unique_ptr<MonitorBase> monitor_; 131 132 bool use_unotify_monitor_ = false; 133 }; 134 135 } // namespace sandbox2 136 137 #endif // SANDBOXED_API_SANDBOX2_SANDBOX2_H_ 138