From 18217e0feb2116534dcb9812dc75556a5cb5d41f Mon Sep 17 00:00:00 2001 From: netblue30 Date: Sun, 10 Jul 2016 08:40:32 -0400 Subject: --noexec --- src/firejail/firejail.h | 2 ++ src/firejail/fs.c | 30 ++++++++++++++++++++++++++++++ src/firejail/main.c | 8 ++++++++ src/firejail/profile.c | 2 ++ 4 files changed, 42 insertions(+) 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) ; void fs_blacklist(void); // remount a directory read-only void fs_rdonly(const char *dir); +// remount a directory noexec, nodev and nosuid +void fs_noexec(const char *dir); // mount /proc and /sys directories void fs_proc_sys_dev_boot(void); // 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 { BLACKLIST_NOLOG, MOUNT_READONLY, MOUNT_TMPFS, + MOUNT_NOEXEC, OPERATION_MAX } OPERATION; @@ -328,6 +329,12 @@ static void disable_file(OPERATION op, const char *filename) { if (arg_debug) printf("Mounting read-only %s\n", fname); fs_rdonly(fname); +// todo: last_disable = SUCCESSFUL; + } + else if (op == MOUNT_NOEXEC) { + if (arg_debug) + printf("Mounting noexec %s\n", fname); + fs_noexec(fname); // todo: last_disable = SUCCESSFUL; } else if (op == MOUNT_TMPFS) { @@ -485,6 +492,10 @@ void fs_blacklist(void) { ptr = entry->data + 10; op = MOUNT_READONLY; } + else if (strncmp(entry->data, "noexec ", 7) == 0) { + ptr = entry->data + 7; + op = MOUNT_NOEXEC; + } else if (strncmp(entry->data, "tmpfs ", 6) == 0) { ptr = entry->data + 6; op = MOUNT_TMPFS; @@ -548,6 +559,25 @@ void fs_rdonly(const char *dir) { fs_logger2("read-only", dir); } } + +void fs_noexec(const char *dir) { + assert(dir); + // check directory exists + struct stat s; + int rv = stat(dir, &s); + if (rv == 0) { + // mount --bind /bin /bin + if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0) + errExit("mount noexec"); + // mount --bind -o remount,ro /bin + if (mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_NOEXEC|MS_NODEV|MS_NOSUID|MS_REC, NULL) < 0) + errExit("mount read-only"); + fs_logger2("noexec", dir); + } +} + + + void fs_rdonly_noexit(const char *dir) { assert(dir); // 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) { profile_check_line(line, 0, NULL); // will exit if something wrong profile_add(line); } + else if (strncmp(argv[i], "--noexec=", 9) == 0) { + char *line; + if (asprintf(&line, "noexec %s", argv[i] + 9) == -1) + errExit("asprintf"); + + profile_check_line(line, 0, NULL); // will exit if something wrong + profile_add(line); + } else if (strncmp(argv[i], "--read-write=", 13) == 0) { char *line; 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) { } else if (strncmp(ptr, "read-only ", 10) == 0) ptr += 10; + else if (strncmp(ptr, "noexec ", 7) == 0) + ptr += 7; else if (strncmp(ptr, "tmpfs ", 6) == 0) { if (getuid() != 0) { fprintf(stderr, "Error: tmpfs available only when running the sandbox as root\n"); -- cgit v1.2.3-54-g00ecf