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 // sandbox2::ForkServer is a class which serves fork()ing request for the 16 // clients. 17 18 #ifndef SANDBOXED_API_SANDBOX2_FORKSERVER_H_ 19 #define SANDBOXED_API_SANDBOX2_FORKSERVER_H_ 20 21 #include <sys/types.h> 22 23 #include <string> 24 #include <vector> 25 26 #include "absl/base/attributes.h" 27 #include "absl/log/log.h" 28 #include "sandboxed_api/util/fileops.h" 29 30 namespace sandbox2 { 31 32 class Comms; 33 class ForkRequest; 34 35 class ForkServer { 36 public: 37 ForkServer(const ForkServer&) = delete; 38 ForkServer& operator=(const ForkServer&) = delete; 39 ForkServer(Comms * comms)40 explicit ForkServer(Comms* comms) : comms_(comms) { 41 if (!Initialize()) { 42 LOG(FATAL) << "Could not initialize the ForkServer"; 43 } 44 } 45 46 // Returns whether the connection with the forkserver was terminated. 47 bool IsTerminated() const; 48 49 // Receives a fork request from the master process. The started process does 50 // not need to be waited for (with waitid/waitpid/wait3/wait4) as the current 51 // process will have the SIGCHLD set to sa_flags=SA_NOCLDWAIT. 52 // Returns values defined as with fork() (-1 means error). 53 pid_t ServeRequest(); 54 55 private: 56 // Creates and launched the child process. 57 void LaunchChild(const ForkRequest& request, int execve_fd, uid_t uid, 58 gid_t gid, sapi::file_util::fileops::FDCloser signaling_fd, 59 sapi::file_util::fileops::FDCloser status_fd, 60 bool avoid_pivot_root) const; 61 62 // Prepares the Fork-Server (worker side, not the requester side) for work by 63 // sanitizing the environment: 64 // - go down if the parent goes down, 65 // - become subreaper - PR_SET_CHILD_SUBREAPER (man prctl), 66 // - don't convert children processes into zombies if they terminate. 67 bool Initialize(); 68 69 // Creates initial namespaces used as a template for namespaced sandboxees 70 void CreateInitialNamespaces(); 71 72 // Prepares arguments for the upcoming execve (if execve was requested). 73 static void PrepareExecveArgs(const ForkRequest& request, 74 std::vector<std::string>* args, 75 std::vector<std::string>* envp); 76 77 // Ensures that no unnecessary file descriptors are lingering after execve(). 78 void SanitizeEnvironment() const; 79 80 // Executes the sandboxee, or exit with Executor::kFailedExecve. 81 static void ExecuteProcess(int execve_fd, const char* const* argv, 82 const char* const* envp) ABSL_ATTRIBUTE_NORETURN; 83 84 // Runs namespace initializers for a sandboxee. 85 static void InitializeNamespaces(const ForkRequest& request, uid_t uid, 86 gid_t gid, bool avoid_pivot_root); 87 88 // Comms channel which is used to send requests to this class. Not owned by 89 // the object. 90 Comms* comms_; 91 int initial_mntns_fd_ = -1; 92 int initial_userns_fd_ = -1; 93 }; 94 95 } // namespace sandbox2 96 97 #endif // SANDBOXED_API_SANDBOX2_FORKSERVER_H_ 98