diff options
Diffstat (limited to 'src/firejail/util.c')
-rw-r--r-- | src/firejail/util.c | 80 |
1 files changed, 2 insertions, 78 deletions
diff --git a/src/firejail/util.c b/src/firejail/util.c index dd70d68a9..18d121ca9 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -1200,69 +1200,6 @@ errexit: | |||
1200 | exit(1); | 1200 | exit(1); |
1201 | } | 1201 | } |
1202 | 1202 | ||
1203 | |||
1204 | // return 1 if the sandbox identified by pid is not fully set up yet or if | ||
1205 | // it is no firejail sandbox at all, return 0 if the sandbox is complete | ||
1206 | int invalid_sandbox(const pid_t pid) { | ||
1207 | // check if a file "ready-for-join" exists | ||
1208 | char *fname; | ||
1209 | if (asprintf(&fname, "/proc/%d/root%s", pid, RUN_READY_FOR_JOIN) == -1) | ||
1210 | errExit("asprintf"); | ||
1211 | EUID_ROOT(); | ||
1212 | FILE *fp = fopen(fname, "re"); | ||
1213 | EUID_USER(); | ||
1214 | free(fname); | ||
1215 | if (!fp) | ||
1216 | return 1; | ||
1217 | // regular file owned by root | ||
1218 | int fd = fileno(fp); | ||
1219 | if (fd == -1) | ||
1220 | errExit("fileno"); | ||
1221 | struct stat s; | ||
1222 | if (fstat(fd, &s) == -1) | ||
1223 | errExit("fstat"); | ||
1224 | if (!S_ISREG(s.st_mode) || s.st_uid != 0) { | ||
1225 | fclose(fp); | ||
1226 | return 1; | ||
1227 | } | ||
1228 | // check if it is non-empty | ||
1229 | char buf[BUFLEN]; | ||
1230 | if (fgets(buf, BUFLEN, fp) == NULL) { | ||
1231 | fclose(fp); | ||
1232 | return 1; | ||
1233 | } | ||
1234 | fclose(fp); | ||
1235 | // confirm "ready" string was written | ||
1236 | if (strncmp(buf, "ready\n", 6) != 0) | ||
1237 | return 1; | ||
1238 | |||
1239 | // walk down the process tree a few nodes, there should be no firejail leaf | ||
1240 | #define MAXNODES 5 | ||
1241 | pid_t current = pid, next; | ||
1242 | int i; | ||
1243 | for (i = 0; i < MAXNODES; i++) { | ||
1244 | if (find_child(current, &next) == 1) { | ||
1245 | // found a leaf | ||
1246 | EUID_ROOT(); | ||
1247 | char *comm = pid_proc_comm(current); | ||
1248 | EUID_USER(); | ||
1249 | if (!comm) { | ||
1250 | fprintf(stderr, "Error: cannot read /proc file\n"); | ||
1251 | exit(1); | ||
1252 | } | ||
1253 | if (strcmp(comm, "firejail") == 0) { | ||
1254 | free(comm); | ||
1255 | return 1; | ||
1256 | } | ||
1257 | free(comm); | ||
1258 | break; | ||
1259 | } | ||
1260 | current = next; | ||
1261 | } | ||
1262 | |||
1263 | return 0; | ||
1264 | } | ||
1265 | |||
1266 | int has_handler(pid_t pid, int signal) { | 1203 | int has_handler(pid_t pid, int signal) { |
1267 | if (signal > 0 && signal <= SIGRTMAX) { | 1204 | if (signal > 0 && signal <= SIGRTMAX) { |
1268 | char *fname; | 1205 | char *fname; |
@@ -1297,21 +1234,8 @@ void enter_network_namespace(pid_t pid) { | |||
1297 | // in case the pid is that of a firejail process, use the pid of the first child process | 1234 | // in case the pid is that of a firejail process, use the pid of the first child process |
1298 | pid_t child = switch_to_child(pid); | 1235 | pid_t child = switch_to_child(pid); |
1299 | 1236 | ||
1300 | // now check if the pid belongs to a firejail sandbox | 1237 | // exit if no permission to join the sandbox |
1301 | if (invalid_sandbox(child)) { | 1238 | check_join_permission(child); |
1302 | fprintf(stderr, "Error: no valid sandbox\n"); | ||
1303 | exit(1); | ||
1304 | } | ||
1305 | |||
1306 | // check privileges for non-root users | ||
1307 | uid_t uid = getuid(); | ||
1308 | if (uid != 0) { | ||
1309 | uid_t sandbox_uid = pid_get_uid(pid); | ||
1310 | if (uid != sandbox_uid) { | ||
1311 | fprintf(stderr, "Error: permission is denied to join a sandbox created by a different user.\n"); | ||
1312 | exit(1); | ||
1313 | } | ||
1314 | } | ||
1315 | 1239 | ||
1316 | // check network namespace | 1240 | // check network namespace |
1317 | char *name; | 1241 | char *name; |