diff options
Diffstat (limited to 'src/firejail/join.c')
-rw-r--r-- | src/firejail/join.c | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/src/firejail/join.c b/src/firejail/join.c index c849b200c..50ef58f4b 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c | |||
@@ -100,21 +100,40 @@ static void extract_nogroups(pid_t pid) { | |||
100 | errExit("asprintf"); | 100 | errExit("asprintf"); |
101 | 101 | ||
102 | struct stat s; | 102 | struct stat s; |
103 | if (stat(fname, &s) == -1) | 103 | if (stat(fname, &s) == -1) { |
104 | free(fname); | ||
104 | return; | 105 | return; |
106 | } | ||
105 | 107 | ||
106 | arg_nogroups = 1; | 108 | arg_nogroups = 1; |
107 | free(fname); | 109 | free(fname); |
108 | } | 110 | } |
109 | 111 | ||
112 | static void extract_nonewprivs(pid_t pid) { | ||
113 | char *fname; | ||
114 | if (asprintf(&fname, "/proc/%d/root%s", pid, RUN_NONEWPRIVS_CFG) == -1) | ||
115 | errExit("asprintf"); | ||
116 | |||
117 | struct stat s; | ||
118 | if (stat(fname, &s) == -1) { | ||
119 | free(fname); | ||
120 | return; | ||
121 | } | ||
122 | |||
123 | arg_nonewprivs = 1; | ||
124 | free(fname); | ||
125 | } | ||
126 | |||
110 | static void extract_cpu(pid_t pid) { | 127 | static void extract_cpu(pid_t pid) { |
111 | char *fname; | 128 | char *fname; |
112 | if (asprintf(&fname, "/proc/%d/root%s", pid, RUN_CPU_CFG) == -1) | 129 | if (asprintf(&fname, "/proc/%d/root%s", pid, RUN_CPU_CFG) == -1) |
113 | errExit("asprintf"); | 130 | errExit("asprintf"); |
114 | 131 | ||
115 | struct stat s; | 132 | struct stat s; |
116 | if (stat(fname, &s) == -1) | 133 | if (stat(fname, &s) == -1) { |
134 | free(fname); | ||
117 | return; | 135 | return; |
136 | } | ||
118 | 137 | ||
119 | // there is a CPU_CFG file, load it! | 138 | // there is a CPU_CFG file, load it! |
120 | load_cpu(fname); | 139 | load_cpu(fname); |
@@ -127,8 +146,10 @@ static void extract_cgroup(pid_t pid) { | |||
127 | errExit("asprintf"); | 146 | errExit("asprintf"); |
128 | 147 | ||
129 | struct stat s; | 148 | struct stat s; |
130 | if (stat(fname, &s) == -1) | 149 | if (stat(fname, &s) == -1) { |
150 | free(fname); | ||
131 | return; | 151 | return; |
152 | } | ||
132 | 153 | ||
133 | // there is a cgroup file CGROUP_CFG, load it! | 154 | // there is a cgroup file CGROUP_CFG, load it! |
134 | load_cgroup(fname); | 155 | load_cgroup(fname); |
@@ -154,7 +175,10 @@ static void extract_caps_seccomp(pid_t pid) { | |||
154 | if (strncmp(buf, "Seccomp:", 8) == 0) { | 175 | if (strncmp(buf, "Seccomp:", 8) == 0) { |
155 | char *ptr = buf + 8; | 176 | char *ptr = buf + 8; |
156 | int val; | 177 | int val; |
157 | sscanf(ptr, "%d", &val); | 178 | if (sscanf(ptr, "%d", &val) != 1) { |
179 | fprintf(stderr, "Error: cannot read stat file for process %u\n", pid); | ||
180 | exit(1); | ||
181 | } | ||
158 | if (val == 2) | 182 | if (val == 2) |
159 | apply_seccomp = 1; | 183 | apply_seccomp = 1; |
160 | break; | 184 | break; |
@@ -162,7 +186,10 @@ static void extract_caps_seccomp(pid_t pid) { | |||
162 | else if (strncmp(buf, "CapBnd:", 7) == 0) { | 186 | else if (strncmp(buf, "CapBnd:", 7) == 0) { |
163 | char *ptr = buf + 7; | 187 | char *ptr = buf + 7; |
164 | unsigned long long val; | 188 | unsigned long long val; |
165 | sscanf(ptr, "%llx", &val); | 189 | if (sscanf(ptr, "%llx", &val) != 1) { |
190 | fprintf(stderr, "Error: cannot read stat file for process %u\n", pid); | ||
191 | exit(1); | ||
192 | } | ||
166 | apply_caps = 1; | 193 | apply_caps = 1; |
167 | caps = val; | 194 | caps = val; |
168 | } | 195 | } |
@@ -229,7 +256,7 @@ pid_t switch_to_child(pid_t pid) { | |||
229 | char *comm = pid_proc_comm(pid); | 256 | char *comm = pid_proc_comm(pid); |
230 | if (!comm) { | 257 | if (!comm) { |
231 | if (errno == ENOENT) { | 258 | if (errno == ENOENT) { |
232 | fprintf(stderr, "Error: cannot find process with id %d\n", pid); | 259 | fprintf(stderr, "Error: cannot find process with pid %d\n", pid); |
233 | exit(1); | 260 | exit(1); |
234 | } | 261 | } |
235 | else { | 262 | else { |
@@ -285,6 +312,7 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
285 | EUID_ROOT(); | 312 | EUID_ROOT(); |
286 | // in user mode set caps seccomp, cpu, cgroup, etc | 313 | // in user mode set caps seccomp, cpu, cgroup, etc |
287 | if (getuid() != 0) { | 314 | if (getuid() != 0) { |
315 | extract_nonewprivs(pid); | ||
288 | extract_caps_seccomp(pid); | 316 | extract_caps_seccomp(pid); |
289 | extract_cpu(pid); | 317 | extract_cpu(pid); |
290 | extract_cgroup(pid); | 318 | extract_cgroup(pid); |
@@ -296,7 +324,7 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
296 | if (cfg.cgroup) // not available for uid 0 | 324 | if (cfg.cgroup) // not available for uid 0 |
297 | set_cgroup(cfg.cgroup); | 325 | set_cgroup(cfg.cgroup); |
298 | 326 | ||
299 | // get umask, it will be set by start_application() | 327 | // set umask, also uid 0 |
300 | extract_umask(pid); | 328 | extract_umask(pid); |
301 | 329 | ||
302 | // join namespaces | 330 | // join namespaces |
@@ -383,6 +411,13 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
383 | caps_set(caps); | 411 | caps_set(caps); |
384 | } | 412 | } |
385 | 413 | ||
414 | // set nonewprivs | ||
415 | if (arg_nonewprivs == 1) { // not available for uid 0 | ||
416 | prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | ||
417 | if (arg_debug) | ||
418 | printf("NO_NEW_PRIVS set\n"); | ||
419 | } | ||
420 | |||
386 | EUID_USER(); | 421 | EUID_USER(); |
387 | // set nice | 422 | // set nice |
388 | if (arg_nice) { | 423 | if (arg_nice) { |