diff options
author | 2018-12-17 23:16:13 +0100 | |
---|---|---|
committer | 2018-12-17 23:16:13 +0100 | |
commit | 9eca281abbb24f97fdb92c06018cd2bd0a5b215e (patch) | |
tree | 1bbefab1443c80bcc90cb4f3f69bc4b7649c6d09 /src | |
parent | Merge pull request #2297 from smitsohu/patch (diff) | |
download | firejail-9eca281abbb24f97fdb92c06018cd2bd0a5b215e.tar.gz firejail-9eca281abbb24f97fdb92c06018cd2bd0a5b215e.tar.zst firejail-9eca281abbb24f97fdb92c06018cd2bd0a5b215e.zip |
join: also check proc file to detect nonewprivs bit
redundant check that adds defense in depth and maybe one
day can replace the other, file based check
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/join.c | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/src/firejail/join.c b/src/firejail/join.c index f52df7f04..3ee069305 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c | |||
@@ -22,9 +22,13 @@ | |||
22 | #include <sys/wait.h> | 22 | #include <sys/wait.h> |
23 | #include <fcntl.h> | 23 | #include <fcntl.h> |
24 | #include <unistd.h> | 24 | #include <unistd.h> |
25 | #include <sys/prctl.h> | ||
26 | #include <errno.h> | 25 | #include <errno.h> |
27 | 26 | ||
27 | #include <sys/prctl.h> | ||
28 | #ifndef PR_SET_NO_NEW_PRIVS | ||
29 | # define PR_SET_NO_NEW_PRIVS 38 | ||
30 | #endif | ||
31 | |||
28 | static int apply_caps = 0; | 32 | static int apply_caps = 0; |
29 | static uint64_t caps = 0; | 33 | static uint64_t caps = 0; |
30 | static int apply_seccomp = 0; | 34 | static int apply_seccomp = 0; |
@@ -164,21 +168,16 @@ static void extract_caps_seccomp(pid_t pid) { | |||
164 | exit(1); | 168 | exit(1); |
165 | } | 169 | } |
166 | FILE *fp = fopen(file, "r"); | 170 | FILE *fp = fopen(file, "r"); |
167 | if (!fp) { | 171 | if (!fp) |
168 | free(file); | 172 | goto errexit; |
169 | fprintf(stderr, "Error: cannot open stat file for process %u\n", pid); | ||
170 | exit(1); | ||
171 | } | ||
172 | 173 | ||
173 | char buf[BUFLEN]; | 174 | char buf[BUFLEN]; |
174 | while (fgets(buf, BUFLEN - 1, fp)) { | 175 | while (fgets(buf, BUFLEN - 1, fp)) { |
175 | if (strncmp(buf, "Seccomp:", 8) == 0) { | 176 | if (strncmp(buf, "Seccomp:", 8) == 0) { |
176 | char *ptr = buf + 8; | 177 | char *ptr = buf + 8; |
177 | int val; | 178 | int val; |
178 | if (sscanf(ptr, "%d", &val) != 1) { | 179 | if (sscanf(ptr, "%d", &val) != 1) |
179 | fprintf(stderr, "Error: cannot read stat file for process %u\n", pid); | 180 | goto errexit; |
180 | exit(1); | ||
181 | } | ||
182 | if (val == 2) | 181 | if (val == 2) |
183 | apply_seccomp = 1; | 182 | apply_seccomp = 1; |
184 | break; | 183 | break; |
@@ -186,16 +185,27 @@ static void extract_caps_seccomp(pid_t pid) { | |||
186 | else if (strncmp(buf, "CapBnd:", 7) == 0) { | 185 | else if (strncmp(buf, "CapBnd:", 7) == 0) { |
187 | char *ptr = buf + 7; | 186 | char *ptr = buf + 7; |
188 | unsigned long long val; | 187 | unsigned long long val; |
189 | if (sscanf(ptr, "%llx", &val) != 1) { | 188 | if (sscanf(ptr, "%llx", &val) != 1) |
190 | fprintf(stderr, "Error: cannot read stat file for process %u\n", pid); | 189 | goto errexit; |
191 | exit(1); | ||
192 | } | ||
193 | apply_caps = 1; | 190 | apply_caps = 1; |
194 | caps = val; | 191 | caps = val; |
195 | } | 192 | } |
193 | else if (strncmp(buf, "NoNewPrivs:", 11) == 0) { | ||
194 | char *ptr = buf + 11; | ||
195 | int val; | ||
196 | if (sscanf(ptr, "%d", &val) != 1) | ||
197 | goto errexit; | ||
198 | if (val) | ||
199 | arg_nonewprivs = 1; | ||
200 | } | ||
196 | } | 201 | } |
197 | fclose(fp); | 202 | fclose(fp); |
198 | free(file); | 203 | free(file); |
204 | return; | ||
205 | |||
206 | errexit: | ||
207 | fprintf(stderr, "Error: cannot read stat file for process %u\n", pid); | ||
208 | exit(1); | ||
199 | } | 209 | } |
200 | 210 | ||
201 | static void extract_user_namespace(pid_t pid) { | 211 | static void extract_user_namespace(pid_t pid) { |
@@ -312,7 +322,7 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
312 | EUID_ROOT(); | 322 | EUID_ROOT(); |
313 | // in user mode set caps seccomp, cpu, cgroup, etc | 323 | // in user mode set caps seccomp, cpu, cgroup, etc |
314 | if (getuid() != 0) { | 324 | if (getuid() != 0) { |
315 | extract_nonewprivs(pid); | 325 | extract_nonewprivs(pid); // redundant on Linux >= 4.10; duplicated in function extract_caps_seccomp |
316 | extract_caps_seccomp(pid); | 326 | extract_caps_seccomp(pid); |
317 | extract_cpu(pid); | 327 | extract_cpu(pid); |
318 | extract_cgroup(pid); | 328 | extract_cgroup(pid); |