1*ec63e07aSXin Li // Copyright 2019 Google LLC 2*ec63e07aSXin Li // 3*ec63e07aSXin Li // Licensed under the Apache License, Version 2.0 (the "License"); 4*ec63e07aSXin Li // you may not use this file except in compliance with the License. 5*ec63e07aSXin Li // You may obtain a copy of the License at 6*ec63e07aSXin Li // 7*ec63e07aSXin Li // https://www.apache.org/licenses/LICENSE-2.0 8*ec63e07aSXin Li // 9*ec63e07aSXin Li // Unless required by applicable law or agreed to in writing, software 10*ec63e07aSXin Li // distributed under the License is distributed on an "AS IS" BASIS, 11*ec63e07aSXin Li // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*ec63e07aSXin Li // See the License for the specific language governing permissions and 13*ec63e07aSXin Li // limitations under the License. 14*ec63e07aSXin Li 15*ec63e07aSXin Li // sandbox2::ForkServer is a class which serves fork()ing request for the 16*ec63e07aSXin Li // clients. 17*ec63e07aSXin Li 18*ec63e07aSXin Li #ifndef SANDBOXED_API_SANDBOX2_FORKSERVER_H_ 19*ec63e07aSXin Li #define SANDBOXED_API_SANDBOX2_FORKSERVER_H_ 20*ec63e07aSXin Li 21*ec63e07aSXin Li #include <sys/types.h> 22*ec63e07aSXin Li 23*ec63e07aSXin Li #include <string> 24*ec63e07aSXin Li #include <vector> 25*ec63e07aSXin Li 26*ec63e07aSXin Li #include "absl/base/attributes.h" 27*ec63e07aSXin Li #include "absl/log/log.h" 28*ec63e07aSXin Li #include "sandboxed_api/util/fileops.h" 29*ec63e07aSXin Li 30*ec63e07aSXin Li namespace sandbox2 { 31*ec63e07aSXin Li 32*ec63e07aSXin Li class Comms; 33*ec63e07aSXin Li class ForkRequest; 34*ec63e07aSXin Li 35*ec63e07aSXin Li class ForkServer { 36*ec63e07aSXin Li public: 37*ec63e07aSXin Li ForkServer(const ForkServer&) = delete; 38*ec63e07aSXin Li ForkServer& operator=(const ForkServer&) = delete; 39*ec63e07aSXin Li ForkServer(Comms * comms)40*ec63e07aSXin Li explicit ForkServer(Comms* comms) : comms_(comms) { 41*ec63e07aSXin Li if (!Initialize()) { 42*ec63e07aSXin Li LOG(FATAL) << "Could not initialize the ForkServer"; 43*ec63e07aSXin Li } 44*ec63e07aSXin Li } 45*ec63e07aSXin Li 46*ec63e07aSXin Li // Returns whether the connection with the forkserver was terminated. 47*ec63e07aSXin Li bool IsTerminated() const; 48*ec63e07aSXin Li 49*ec63e07aSXin Li // Receives a fork request from the master process. The started process does 50*ec63e07aSXin Li // not need to be waited for (with waitid/waitpid/wait3/wait4) as the current 51*ec63e07aSXin Li // process will have the SIGCHLD set to sa_flags=SA_NOCLDWAIT. 52*ec63e07aSXin Li // Returns values defined as with fork() (-1 means error). 53*ec63e07aSXin Li pid_t ServeRequest(); 54*ec63e07aSXin Li 55*ec63e07aSXin Li private: 56*ec63e07aSXin Li // Creates and launched the child process. 57*ec63e07aSXin Li void LaunchChild(const ForkRequest& request, int execve_fd, uid_t uid, 58*ec63e07aSXin Li gid_t gid, sapi::file_util::fileops::FDCloser signaling_fd, 59*ec63e07aSXin Li sapi::file_util::fileops::FDCloser status_fd, 60*ec63e07aSXin Li bool avoid_pivot_root) const; 61*ec63e07aSXin Li 62*ec63e07aSXin Li // Prepares the Fork-Server (worker side, not the requester side) for work by 63*ec63e07aSXin Li // sanitizing the environment: 64*ec63e07aSXin Li // - go down if the parent goes down, 65*ec63e07aSXin Li // - become subreaper - PR_SET_CHILD_SUBREAPER (man prctl), 66*ec63e07aSXin Li // - don't convert children processes into zombies if they terminate. 67*ec63e07aSXin Li bool Initialize(); 68*ec63e07aSXin Li 69*ec63e07aSXin Li // Creates initial namespaces used as a template for namespaced sandboxees 70*ec63e07aSXin Li void CreateInitialNamespaces(); 71*ec63e07aSXin Li 72*ec63e07aSXin Li // Prepares arguments for the upcoming execve (if execve was requested). 73*ec63e07aSXin Li static void PrepareExecveArgs(const ForkRequest& request, 74*ec63e07aSXin Li std::vector<std::string>* args, 75*ec63e07aSXin Li std::vector<std::string>* envp); 76*ec63e07aSXin Li 77*ec63e07aSXin Li // Ensures that no unnecessary file descriptors are lingering after execve(). 78*ec63e07aSXin Li void SanitizeEnvironment() const; 79*ec63e07aSXin Li 80*ec63e07aSXin Li // Executes the sandboxee, or exit with Executor::kFailedExecve. 81*ec63e07aSXin Li static void ExecuteProcess(int execve_fd, const char* const* argv, 82*ec63e07aSXin Li const char* const* envp) ABSL_ATTRIBUTE_NORETURN; 83*ec63e07aSXin Li 84*ec63e07aSXin Li // Runs namespace initializers for a sandboxee. 85*ec63e07aSXin Li static void InitializeNamespaces(const ForkRequest& request, uid_t uid, 86*ec63e07aSXin Li gid_t gid, bool avoid_pivot_root); 87*ec63e07aSXin Li 88*ec63e07aSXin Li // Comms channel which is used to send requests to this class. Not owned by 89*ec63e07aSXin Li // the object. 90*ec63e07aSXin Li Comms* comms_; 91*ec63e07aSXin Li int initial_mntns_fd_ = -1; 92*ec63e07aSXin Li int initial_userns_fd_ = -1; 93*ec63e07aSXin Li }; 94*ec63e07aSXin Li 95*ec63e07aSXin Li } // namespace sandbox2 96*ec63e07aSXin Li 97*ec63e07aSXin Li #endif // SANDBOXED_API_SANDBOX2_FORKSERVER_H_ 98