projects/guix·blob ruby-team · refs

135 lines · 5.2 KiB

1#pragma once
2
3#include <util.hh>
4#include <map>
5#include <stddef.h>
6#ifdef __linux__
7#include <linux/filter.h>
8#endif
9
10namespace nix {
11struct SpawnContext; /* Forward declaration */
12typedef void (Action)(SpawnContext & ctx);
13
14struct Phase {
15 string label;
16 Action * action;
17};
18
19typedef std::vector<Phase> Phases;
20
21/* Common structure read from / written to by setup phases in a newly-spawned
22 child process. Configure this to determine which per-process or
23 per-thread attributes should be set. */
24struct SpawnContext {
25 ssize_t currentPhase = 0;
26 Phases phases;
27 Strings args; /* Will be passed as-is to execve, does not implicitly add
28 * program basename as argv[0]! */
29 Path program;
30 bool inheritEnv = true; /* True to use the current environment after env
31 * has been applied to it, false to use strictly
32 * env. */
33 std::map<string, string> env;
34 bool setPersona = false;
35 int persona;
36 int logFD = -1; /* -1 to keep stdout and stderr */
37 set<int> earlyCloseFDs; /* Typically for closing inherited unused pipe or
38 * socket ends to prevent hangs when reading or
39 * writing. */
40 bool closeMostFDs = false;
41 set<int> preserveFDs; /* 0, 1, and 2 are always implicitly preserved. */
42 bool setStdin = false;
43 int stdinFD = -1; /* fd or -1 */
44 Path stdinFile; /* used if stdinFD == -1 */
45 bool setuid = false;
46 uid_t user;
47 bool setgid = false;
48 gid_t group;
49 bool setSupplementaryGroups = false;
50 std::vector<gid_t> supplementaryGroups;
51 bool setsid = false;
52 bool oomSacrifice = false; /* Whether to attempt to offer the child
53 * process to the OOM killer if possible. */
54 bool setcwd = false;
55 Path cwd;
56 bool signalSetupSuccess = false; /* Whether the parent is waiting for a
57 * message that setup succeeded. By
58 * default success is signaled by
59 * writing a single newline to stderr. */
60 bool dropAmbientCapabilities = false; /* Whether to drop ambient
61 * capabilities if on a system that
62 * supports them. */
63 bool setNoNewPrivs = false;
64 bool addSeccompFilter = false;
65#if __linux__
66 std::vector<struct sock_filter> seccompFilter;
67#endif
68 bool doChroot = false;
69 Path chrootRootDir;
70 void * extraData; /* Extra user data */
71};
72
73/* Like SpawnContext, but with extra fields for setting up Linux namespaces,
74 as created by clone or unshare. */
75struct CloneSpawnContext : SpawnContext {
76 int cloneFlags = 0;
77 std::map<Path, Path> filesInChroot; /* map from path inside chroot to
78 * path outside of chroot */
79 set<Path> readOnlyFilesInChroot;
80 bool mountTmpfsOnChroot = false; /* req. CLONE_NEWNS and doChroot */
81 bool mountProc = false;
82 bool mountDevshm = false;
83 bool maybeMountDevpts = false; /* Only mounted if /dev/ptmx doesn't exist
84 * after any chroot, if applicable. */
85 bool lockMounts = false; /* Whether to lock mounts by creating a fresh
86 * user and mount namespace, see
87 * mount_namespaces(7). */
88 bool lockMountsMapAll = false; /* Whether to map all currently-mapped
89 users and groups when locking mounts or
90 only the current ones. */
91 bool lockMountsAllowSetgroups = false;
92 int setupFD = -1; /* Used for userns init sync and other stuff */
93 string hostname; /* Requires CLONE_NEWUTS */
94 string domainname; /* Same */
95 bool initLoopback = false; /* Also requires CLONE_NEWNET in cloneFlags */
96 /* These may be used if CLONE_NEWUSER in cloneFlags. These are to be
97 used when an id other than the current uid/gid has been mapped into the
98 child's user namespace, and it now needs to setuid/setgid to an id
99 that is mapped. */
100 bool usernsSetuid = false;
101 uid_t usernsUser;
102 bool usernsSetgid = false;
103 gid_t usernsGroup;
104};
105
106void addPhaseAfter(Phases & phases, string afterLabel, string addLabel, Action addAction);
107
108void addPhaseBefore(Phases & phases, string beforeLabel, string addLabel, Action addAction);
109
110void prependPhase(Phases & phases, string addLabel, Action addAction);
111
112void appendPhase(Phases & phases, string addLabel, Action addAction);
113
114void deletePhase(Phases & phases, string delLabel);
115
116void replacePhase(Phases & phases, string replaceLabel, Action newAction);
117
118Action execAction; // used from 'build.cc'
119
120Phases getBasicSpawnPhases();
121Phases getCloneSpawnPhases();
122
123/* Helpers */
124
125void unshareAndInitUserns(int flags, const string & uidMap,
126 const string & gidMap, bool allowSetgroups);
127
128/* Run the phases of ctx in order, catching and reporting any exception, and
129 * exiting in all cases. */
130void runChildSetup(SpawnContext & ctx);
131
132/* Create a new process using clone that will immediately call runChildSetup
133 * with the provided CloneSpawnContext. Return the pid of the new process. */
134int cloneChild(CloneSpawnContext & ctx);
135}