xref: /aosp_15_r20/external/sandboxed-api/sandboxed_api/sandbox2/forkserver.h (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
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