xref: /aosp_15_r20/external/sandboxed-api/sandboxed_api/sandbox2/global_forkclient.h (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
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 // StartGlobalForkServer() is called early in a process using a constructor, so
16 // it can fork() safely (in a single-threaded context)
17 
18 #ifndef SANDBOXED_API_SANDBOX2_GLOBAL_FORKCLIENT_H_
19 #define SANDBOXED_API_SANDBOX2_GLOBAL_FORKCLIENT_H_
20 
21 #include <sys/types.h>
22 
23 #include <bitset>
24 #include <cstddef>
25 #include <string>
26 
27 #include "absl/base/thread_annotations.h"
28 #include "absl/flags/declare.h"
29 #include "absl/strings/string_view.h"
30 #include "absl/synchronization/mutex.h"
31 #include "sandboxed_api/sandbox2/comms.h"
32 #include "sandboxed_api/sandbox2/fork_client.h"
33 #include "sandboxed_api/sandbox2/forkserver.pb.h"
34 
35 namespace sandbox2 {
36 
37 enum class GlobalForkserverStartMode {
38   kOnDemand,
39   // MUST be the last element
40   kNumGlobalForkserverStartModes,
41 };
42 
43 class GlobalForkClient {
44  public:
GlobalForkClient(int fd,pid_t pid)45   GlobalForkClient(int fd, pid_t pid)
46       : comms_(fd), fork_client_(pid, &comms_, /*is_global=*/true) {}
47 
48   static SandboxeeProcess SendRequest(const ForkRequest& request, int exec_fd,
49                                       int comms_fd)
50       ABSL_LOCKS_EXCLUDED(instance_mutex_);
51   static pid_t GetPid() ABSL_LOCKS_EXCLUDED(instance_mutex_);
52 
EnsureStarted()53   static void EnsureStarted() ABSL_LOCKS_EXCLUDED(instance_mutex_) {
54     EnsureStarted(GlobalForkserverStartMode::kOnDemand);
55   }
56   static void Shutdown() ABSL_LOCKS_EXCLUDED(instance_mutex_);
57   static bool IsStarted() ABSL_LOCKS_EXCLUDED(instance_mutex_);
58 
59  private:
60   friend void StartGlobalForkserverFromLibCtor();
61 
62   static void ForceStart() ABSL_LOCKS_EXCLUDED(instance_mutex_);
63   static void EnsureStarted(GlobalForkserverStartMode mode)
64       ABSL_LOCKS_EXCLUDED(instance_mutex_);
65   static void EnsureStartedLocked(GlobalForkserverStartMode mode)
66       ABSL_EXCLUSIVE_LOCKS_REQUIRED(instance_mutex_);
67 
68   static absl::Mutex instance_mutex_;
69   static GlobalForkClient* instance_ ABSL_GUARDED_BY(instance_mutex_);
70 
71   Comms comms_;
72   ForkClient fork_client_;
73 };
74 
75 class GlobalForkserverStartModeSet {
76  public:
77   static constexpr size_t kSize = static_cast<size_t>(
78       GlobalForkserverStartMode::kNumGlobalForkserverStartModes);
79 
GlobalForkserverStartModeSet()80   GlobalForkserverStartModeSet() {}
GlobalForkserverStartModeSet(GlobalForkserverStartMode value)81   explicit GlobalForkserverStartModeSet(GlobalForkserverStartMode value) {
82     value_[static_cast<size_t>(value)] = true;
83   }
84   GlobalForkserverStartModeSet& operator|=(GlobalForkserverStartMode value) {
85     value_[static_cast<size_t>(value)] = true;
86     return *this;
87   }
88   GlobalForkserverStartModeSet operator|(
89       GlobalForkserverStartMode value) const {
90     GlobalForkserverStartModeSet rv(*this);
91     rv |= value;
92     return rv;
93   }
contains(GlobalForkserverStartMode value)94   bool contains(GlobalForkserverStartMode value) const {
95     return value_[static_cast<size_t>(value)];
96   }
empty()97   bool empty() { return value_.none(); }
98 
99  private:
100   std::bitset<kSize> value_;
101 };
102 
103 bool AbslParseFlag(absl::string_view text, GlobalForkserverStartModeSet* out,
104                    std::string* error);
105 std::string AbslUnparseFlag(GlobalForkserverStartModeSet in);
106 
107 }  // namespace sandbox2
108 
109 ABSL_DECLARE_FLAG(sandbox2::GlobalForkserverStartModeSet,
110                   sandbox2_forkserver_start_mode);
111 ABSL_DECLARE_FLAG(std::string, sandbox2_forkserver_binary_path);
112 
113 #endif  // SANDBOXED_API_SANDBOX2_GLOBAL_FORKCLIENT_H_
114