diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/firejail.h | 2 | ||||
-rw-r--r-- | src/firejail/fs.c | 30 | ||||
-rw-r--r-- | src/firejail/main.c | 8 | ||||
-rw-r--r-- | src/firejail/profile.c | 2 |
4 files changed, 42 insertions, 0 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index c18dacbbb..8856986e6 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -313,6 +313,8 @@ void fs_delete_cp_command(void) ; | |||
313 | void fs_blacklist(void); | 313 | void fs_blacklist(void); |
314 | // remount a directory read-only | 314 | // remount a directory read-only |
315 | void fs_rdonly(const char *dir); | 315 | void fs_rdonly(const char *dir); |
316 | // remount a directory noexec, nodev and nosuid | ||
317 | void fs_noexec(const char *dir); | ||
316 | // mount /proc and /sys directories | 318 | // mount /proc and /sys directories |
317 | void fs_proc_sys_dev_boot(void); | 319 | void fs_proc_sys_dev_boot(void); |
318 | // build a basic read-only filesystem | 320 | // build a basic read-only filesystem |
diff --git a/src/firejail/fs.c b/src/firejail/fs.c index 5665ab456..de59b6676 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c | |||
@@ -228,6 +228,7 @@ typedef enum { | |||
228 | BLACKLIST_NOLOG, | 228 | BLACKLIST_NOLOG, |
229 | MOUNT_READONLY, | 229 | MOUNT_READONLY, |
230 | MOUNT_TMPFS, | 230 | MOUNT_TMPFS, |
231 | MOUNT_NOEXEC, | ||
231 | OPERATION_MAX | 232 | OPERATION_MAX |
232 | } OPERATION; | 233 | } OPERATION; |
233 | 234 | ||
@@ -330,6 +331,12 @@ static void disable_file(OPERATION op, const char *filename) { | |||
330 | fs_rdonly(fname); | 331 | fs_rdonly(fname); |
331 | // todo: last_disable = SUCCESSFUL; | 332 | // todo: last_disable = SUCCESSFUL; |
332 | } | 333 | } |
334 | else if (op == MOUNT_NOEXEC) { | ||
335 | if (arg_debug) | ||
336 | printf("Mounting noexec %s\n", fname); | ||
337 | fs_noexec(fname); | ||
338 | // todo: last_disable = SUCCESSFUL; | ||
339 | } | ||
333 | else if (op == MOUNT_TMPFS) { | 340 | else if (op == MOUNT_TMPFS) { |
334 | if (S_ISDIR(s.st_mode)) { | 341 | if (S_ISDIR(s.st_mode)) { |
335 | if (arg_debug) | 342 | if (arg_debug) |
@@ -485,6 +492,10 @@ void fs_blacklist(void) { | |||
485 | ptr = entry->data + 10; | 492 | ptr = entry->data + 10; |
486 | op = MOUNT_READONLY; | 493 | op = MOUNT_READONLY; |
487 | } | 494 | } |
495 | else if (strncmp(entry->data, "noexec ", 7) == 0) { | ||
496 | ptr = entry->data + 7; | ||
497 | op = MOUNT_NOEXEC; | ||
498 | } | ||
488 | else if (strncmp(entry->data, "tmpfs ", 6) == 0) { | 499 | else if (strncmp(entry->data, "tmpfs ", 6) == 0) { |
489 | ptr = entry->data + 6; | 500 | ptr = entry->data + 6; |
490 | op = MOUNT_TMPFS; | 501 | op = MOUNT_TMPFS; |
@@ -548,6 +559,25 @@ void fs_rdonly(const char *dir) { | |||
548 | fs_logger2("read-only", dir); | 559 | fs_logger2("read-only", dir); |
549 | } | 560 | } |
550 | } | 561 | } |
562 | |||
563 | void fs_noexec(const char *dir) { | ||
564 | assert(dir); | ||
565 | // check directory exists | ||
566 | struct stat s; | ||
567 | int rv = stat(dir, &s); | ||
568 | if (rv == 0) { | ||
569 | // mount --bind /bin /bin | ||
570 | if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
571 | errExit("mount noexec"); | ||
572 | // mount --bind -o remount,ro /bin | ||
573 | if (mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_NOEXEC|MS_NODEV|MS_NOSUID|MS_REC, NULL) < 0) | ||
574 | errExit("mount read-only"); | ||
575 | fs_logger2("noexec", dir); | ||
576 | } | ||
577 | } | ||
578 | |||
579 | |||
580 | |||
551 | void fs_rdonly_noexit(const char *dir) { | 581 | void fs_rdonly_noexit(const char *dir) { |
552 | assert(dir); | 582 | assert(dir); |
553 | // check directory exists | 583 | // check directory exists |
diff --git a/src/firejail/main.c b/src/firejail/main.c index 35f825a07..232a57499 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -1192,6 +1192,14 @@ int main(int argc, char **argv) { | |||
1192 | profile_check_line(line, 0, NULL); // will exit if something wrong | 1192 | profile_check_line(line, 0, NULL); // will exit if something wrong |
1193 | profile_add(line); | 1193 | profile_add(line); |
1194 | } | 1194 | } |
1195 | else if (strncmp(argv[i], "--noexec=", 9) == 0) { | ||
1196 | char *line; | ||
1197 | if (asprintf(&line, "noexec %s", argv[i] + 9) == -1) | ||
1198 | errExit("asprintf"); | ||
1199 | |||
1200 | profile_check_line(line, 0, NULL); // will exit if something wrong | ||
1201 | profile_add(line); | ||
1202 | } | ||
1195 | else if (strncmp(argv[i], "--read-write=", 13) == 0) { | 1203 | else if (strncmp(argv[i], "--read-write=", 13) == 0) { |
1196 | char *line; | 1204 | char *line; |
1197 | if (asprintf(&line, "read-write %s", argv[i] + 13) == -1) | 1205 | if (asprintf(&line, "read-write %s", argv[i] + 13) == -1) |
diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 1106ed84e..40e2e4330 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c | |||
@@ -747,6 +747,8 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
747 | } | 747 | } |
748 | else if (strncmp(ptr, "read-only ", 10) == 0) | 748 | else if (strncmp(ptr, "read-only ", 10) == 0) |
749 | ptr += 10; | 749 | ptr += 10; |
750 | else if (strncmp(ptr, "noexec ", 7) == 0) | ||
751 | ptr += 7; | ||
750 | else if (strncmp(ptr, "tmpfs ", 6) == 0) { | 752 | else if (strncmp(ptr, "tmpfs ", 6) == 0) { |
751 | if (getuid() != 0) { | 753 | if (getuid() != 0) { |
752 | fprintf(stderr, "Error: tmpfs available only when running the sandbox as root\n"); | 754 | fprintf(stderr, "Error: tmpfs available only when running the sandbox as root\n"); |