diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/firejail.h | 9 | ||||
-rw-r--r-- | src/firejail/fs.c | 22 | ||||
-rw-r--r-- | src/firejail/preproc.c | 58 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 4 | ||||
-rw-r--r-- | src/firejail/seccomp.c | 37 | ||||
-rw-r--r-- | src/fseccomp/main.c | 4 | ||||
-rw-r--r-- | src/man/firejail.txt | 4 |
7 files changed, 28 insertions, 110 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 2562094d3..2e031ce04 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -47,10 +47,14 @@ | |||
47 | #define RUN_BIN_DIR "/run/firejail/mnt/bin" | 47 | #define RUN_BIN_DIR "/run/firejail/mnt/bin" |
48 | #define RUN_PULSE_DIR "/run/firejail/mnt/pulse" | 48 | #define RUN_PULSE_DIR "/run/firejail/mnt/pulse" |
49 | 49 | ||
50 | #define RUN_SECCOMP_CFG "/run/firejail/mnt/seccomp" // configured filter | ||
51 | #define RUN_SECCOMP_PROTOCOL "/run/firejail/mnt/seccomp.protocol" // protocol filter | 50 | #define RUN_SECCOMP_PROTOCOL "/run/firejail/mnt/seccomp.protocol" // protocol filter |
51 | #define RUN_SECCOMP_CFG "/run/firejail/mnt/seccomp" // configured filter | ||
52 | #define RUN_SECCOMP_AMD64 "/run/firejail/mnt/seccomp.amd64" // amd64 filter installed on i386 architectures | 52 | #define RUN_SECCOMP_AMD64 "/run/firejail/mnt/seccomp.amd64" // amd64 filter installed on i386 architectures |
53 | #define RUN_SECCOMP_I386 "/run/firejail/mnt/seccomp.i386" // i386 filter installed on amd64 architectures | 53 | #define RUN_SECCOMP_I386 "/run/firejail/mnt/seccomp.i386" // i386 filter installed on amd64 architectures |
54 | #define PATH_SECCOMP_DEFAULT (LIBDIR "/firejail/seccomp") // default filter built during make | ||
55 | #define PATH_SECCOMP_DEFAULT_DEBUG (LIBDIR "/firejail/seccomp.debug") // default filter built during make | ||
56 | #define PATH_SECCOMP_AMD64 (LIBDIR "/firejail/seccomp.amd64") // amd64 filter built during make | ||
57 | #define PATH_SECCOMP_I386 (LIBDIR "/firejail/seccomp.i386") // i386 filter built during make | ||
54 | 58 | ||
55 | 59 | ||
56 | #define RUN_DEV_DIR "/run/firejail/mnt/dev" | 60 | #define RUN_DEV_DIR "/run/firejail/mnt/dev" |
@@ -374,9 +378,6 @@ void net_config_interface(const char *dev, uint32_t ip, uint32_t mask, int mtu); | |||
374 | // preproc.c | 378 | // preproc.c |
375 | void preproc_build_firejail_dir(void); | 379 | void preproc_build_firejail_dir(void); |
376 | void preproc_mount_mnt_dir(void); | 380 | void preproc_mount_mnt_dir(void); |
377 | void preproc_build_cp_command(void); | ||
378 | void preproc_delete_cp_command(void) ; | ||
379 | void preproc_remount_mnt_dir(void); | ||
380 | 381 | ||
381 | // fs.c | 382 | // fs.c |
382 | // blacklist files or directoies by mounting empty files on top of them | 383 | // blacklist files or directoies by mounting empty files on top of them |
diff --git a/src/firejail/fs.c b/src/firejail/fs.c index 7ff7e3c59..5774ebf6a 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c | |||
@@ -1010,24 +1010,13 @@ void fs_chroot(const char *rootdir) { | |||
1010 | create_empty_dir_as_root(rundir, 0755); | 1010 | create_empty_dir_as_root(rundir, 0755); |
1011 | free(rundir); | 1011 | free(rundir); |
1012 | 1012 | ||
1013 | // create /run/firejail/mnt directory in chroot and mount a tmpfs | 1013 | // create /run/firejail/mnt directory in chroot and mount the current one |
1014 | if (asprintf(&rundir, "%s/run/firejail/mnt", rootdir) == -1) | 1014 | if (asprintf(&rundir, "%s%s", rootdir, RUN_MNT_DIR) == -1) |
1015 | errExit("asprintf"); | 1015 | errExit("asprintf"); |
1016 | create_empty_dir_as_root(rundir, 0755); | 1016 | create_empty_dir_as_root(rundir, 0755); |
1017 | if (mount("tmpfs", rundir, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | 1017 | if (mount(RUN_MNT_DIR, rundir, NULL, MS_BIND|MS_REC, NULL) < 0) |
1018 | errExit("mounting /run/firejail/mnt"); | 1018 | errExit("mount bind"); |
1019 | fs_logger2("tmpfs", RUN_MNT_DIR); | ||
1020 | free(rundir); | ||
1021 | 1019 | ||
1022 | // retrieve seccomp.protocol | ||
1023 | struct stat s; | ||
1024 | if (stat(RUN_SECCOMP_PROTOCOL, &s) == 0) { | ||
1025 | if (asprintf(&rundir, "%s%s", rootdir, RUN_SECCOMP_PROTOCOL) == -1) | ||
1026 | errExit("asprintf"); | ||
1027 | copy_file(RUN_SECCOMP_PROTOCOL, rundir, getuid(), getgid(), 0644); | ||
1028 | free(rundir); | ||
1029 | } | ||
1030 | |||
1031 | // copy /etc/resolv.conf in chroot directory | 1020 | // copy /etc/resolv.conf in chroot directory |
1032 | // if resolv.conf in chroot is a symbolic link, this will fail | 1021 | // if resolv.conf in chroot is a symbolic link, this will fail |
1033 | // no exit on error, let the user deal with the problem | 1022 | // no exit on error, let the user deal with the problem |
@@ -1053,9 +1042,6 @@ void fs_chroot(const char *rootdir) { | |||
1053 | if (chroot(rootdir) < 0) | 1042 | if (chroot(rootdir) < 0) |
1054 | errExit("chroot"); | 1043 | errExit("chroot"); |
1055 | 1044 | ||
1056 | // create all other /run/firejail files and directories | ||
1057 | preproc_build_firejail_dir(); | ||
1058 | |||
1059 | if (checkcfg(CFG_CHROOT_DESKTOP)) { | 1045 | if (checkcfg(CFG_CHROOT_DESKTOP)) { |
1060 | // update /var directory in order to support multiple sandboxes running on the same root directory | 1046 | // update /var directory in order to support multiple sandboxes running on the same root directory |
1061 | // if (!arg_private_dev) | 1047 | // if (!arg_private_dev) |
diff --git a/src/firejail/preproc.c b/src/firejail/preproc.c index ea4e6743f..d2db7d3dd 100644 --- a/src/firejail/preproc.c +++ b/src/firejail/preproc.c | |||
@@ -56,9 +56,9 @@ void preproc_build_firejail_dir(void) { | |||
56 | create_empty_dir_as_root(RUN_FIREJAIL_APPIMAGE_DIR, 0755); | 56 | create_empty_dir_as_root(RUN_FIREJAIL_APPIMAGE_DIR, 0755); |
57 | } | 57 | } |
58 | 58 | ||
59 | if (stat(RUN_MNT_DIR, &s)) { | 59 | if (stat(RUN_MNT_DIR, &s)) { |
60 | create_empty_dir_as_root(RUN_MNT_DIR, 0755); | 60 | create_empty_dir_as_root(RUN_MNT_DIR, 0755); |
61 | } | 61 | } |
62 | 62 | ||
63 | create_empty_file_as_root(RUN_RO_FILE, S_IRUSR); | 63 | create_empty_file_as_root(RUN_RO_FILE, S_IRUSR); |
64 | create_empty_dir_as_root(RUN_RO_DIR, S_IRUSR); | 64 | create_empty_dir_as_root(RUN_RO_DIR, S_IRUSR); |
@@ -75,51 +75,17 @@ void preproc_mount_mnt_dir(void) { | |||
75 | tmpfs_mounted = 1; | 75 | tmpfs_mounted = 1; |
76 | fs_logger2("tmpfs", RUN_MNT_DIR); | 76 | fs_logger2("tmpfs", RUN_MNT_DIR); |
77 | 77 | ||
78 | // create all seccomp files | 78 | //copy defaultl seccomp files |
79 | // as root, create RUN_SECCOMP_I386 file | 79 | copy_file(PATH_SECCOMP_I386, RUN_SECCOMP_I386, getuid(), getgid(), 0644); |
80 | create_empty_file_as_root(RUN_SECCOMP_I386, 0644); | 80 | copy_file(PATH_SECCOMP_AMD64, RUN_SECCOMP_AMD64, getuid(), getgid(), 0644); |
81 | if (set_perms(RUN_SECCOMP_I386, getuid(), getgid(), 0644)) | 81 | if (arg_allow_debuggers) |
82 | errExit("set_perms"); | 82 | copy_file(PATH_SECCOMP_DEFAULT_DEBUG, RUN_SECCOMP_CFG, getuid(), getgid(), 0644); |
83 | 83 | else | |
84 | // as root, create RUN_SECCOMP_AMD64 file | 84 | copy_file(PATH_SECCOMP_DEFAULT, RUN_SECCOMP_CFG, getuid(), getgid(), 0644); |
85 | create_empty_file_as_root(RUN_SECCOMP_AMD64, 0644); | 85 | |
86 | if (set_perms(RUN_SECCOMP_AMD64, getuid(), getgid(), 0644)) | 86 | // as root, create an empty RUN_SECCOMP_PROTOCOL file |
87 | errExit("set_perms"); | ||
88 | |||
89 | // as root, create RUN_SECCOMP file | ||
90 | create_empty_file_as_root(RUN_SECCOMP_CFG, 0644); | ||
91 | if (set_perms(RUN_SECCOMP_CFG, getuid(), getgid(), 0644)) | ||
92 | errExit("set_perms"); | ||
93 | |||
94 | // as root, create RUN_SECCOMP_PROTOCOL file | ||
95 | create_empty_file_as_root(RUN_SECCOMP_PROTOCOL, 0644); | 87 | create_empty_file_as_root(RUN_SECCOMP_PROTOCOL, 0644); |
96 | if (set_perms(RUN_SECCOMP_PROTOCOL, getuid(), getgid(), 0644)) | 88 | if (set_perms(RUN_SECCOMP_PROTOCOL, getuid(), getgid(), 0644)) |
97 | errExit("set_perms"); | 89 | errExit("set_perms"); |
98 | } | 90 | } |
99 | } | 91 | } |
100 | |||
101 | // grab a copy of cp command | ||
102 | void preproc_build_cp_command(void) { | ||
103 | struct stat s; | ||
104 | preproc_mount_mnt_dir(); | ||
105 | if (stat(RUN_CP_COMMAND, &s)) { | ||
106 | char* fname = realpath("/bin/cp", NULL); | ||
107 | if (fname == NULL || stat(fname, &s) || is_link(fname)) { | ||
108 | fprintf(stderr, "Error: invalid /bin/cp\n"); | ||
109 | exit(1); | ||
110 | } | ||
111 | int rv = copy_file(fname, RUN_CP_COMMAND, 0, 0, 0755); | ||
112 | if (rv) { | ||
113 | fprintf(stderr, "Error: cannot access /bin/cp\n"); | ||
114 | exit(1); | ||
115 | } | ||
116 | ASSERT_PERMS(RUN_CP_COMMAND, 0, 0, 0755); | ||
117 | |||
118 | free(fname); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | // delete the temporary cp command | ||
123 | void preproc_delete_cp_command(void) { | ||
124 | unlink(RUN_CP_COMMAND); | ||
125 | } | ||
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index c2e053b0c..ad77caeb2 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -555,12 +555,9 @@ int sandbox(void* sandbox_arg) { | |||
555 | 555 | ||
556 | //**************************** | 556 | //**************************** |
557 | // fs pre-processing: | 557 | // fs pre-processing: |
558 | // - copy some commands under /run | ||
559 | // - build seccomp filters | 558 | // - build seccomp filters |
560 | // - create an empty /etc/ld.so.preload | 559 | // - create an empty /etc/ld.so.preload |
561 | //**************************** | 560 | //**************************** |
562 | preproc_build_cp_command(); | ||
563 | |||
564 | #ifdef HAVE_SECCOMP | 561 | #ifdef HAVE_SECCOMP |
565 | if (cfg.protocol) { | 562 | if (cfg.protocol) { |
566 | if (arg_debug) | 563 | if (arg_debug) |
@@ -765,7 +762,6 @@ int sandbox(void* sandbox_arg) { | |||
765 | //**************************** | 762 | //**************************** |
766 | // fs post-processing | 763 | // fs post-processing |
767 | //**************************** | 764 | //**************************** |
768 | preproc_delete_cp_command(); | ||
769 | fs_logger_print(); | 765 | fs_logger_print(); |
770 | fs_logger_change_owner(); | 766 | fs_logger_change_owner(); |
771 | 767 | ||
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c index 4a2221e98..4678f366b 100644 --- a/src/firejail/seccomp.c +++ b/src/firejail/seccomp.c | |||
@@ -92,20 +92,8 @@ int seccomp_load(const char *fname) { | |||
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | |||
96 | |||
97 | |||
98 | // i386 filter installed on amd64 architectures | 95 | // i386 filter installed on amd64 architectures |
99 | void seccomp_filter_32(void) { | 96 | void seccomp_filter_32(void) { |
100 | if (arg_debug) | ||
101 | printf("Build secondary 32-bit filter\n"); | ||
102 | |||
103 | // build the seccomp filter as a regular user | ||
104 | int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4, | ||
105 | PATH_FSECCOMP, "secondary", "32", RUN_SECCOMP_I386); | ||
106 | if (rv) | ||
107 | exit(rv); | ||
108 | |||
109 | if (seccomp_load(RUN_SECCOMP_I386) == 0) { | 97 | if (seccomp_load(RUN_SECCOMP_I386) == 0) { |
110 | if (arg_debug) | 98 | if (arg_debug) |
111 | printf("Dual i386/amd64 seccomp filter configured\n"); | 99 | printf("Dual i386/amd64 seccomp filter configured\n"); |
@@ -114,22 +102,12 @@ void seccomp_filter_32(void) { | |||
114 | 102 | ||
115 | // amd64 filter installed on i386 architectures | 103 | // amd64 filter installed on i386 architectures |
116 | void seccomp_filter_64(void) { | 104 | void seccomp_filter_64(void) { |
117 | if (arg_debug) | ||
118 | printf("Build secondary 64-bit filter\n"); | ||
119 | |||
120 | // build the seccomp filter as a regular user | ||
121 | int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4, | ||
122 | PATH_FSECCOMP, "secondary", "64", RUN_SECCOMP_AMD64); | ||
123 | if (rv) | ||
124 | exit(rv); | ||
125 | |||
126 | if (seccomp_load(RUN_SECCOMP_AMD64) == 0) { | 105 | if (seccomp_load(RUN_SECCOMP_AMD64) == 0) { |
127 | if (arg_debug) | 106 | if (arg_debug) |
128 | printf("Dual i386/amd64 seccomp filter configured\n"); | 107 | printf("Dual i386/amd64 seccomp filter configured\n"); |
129 | } | 108 | } |
130 | } | 109 | } |
131 | 110 | ||
132 | |||
133 | // drop filter for seccomp option | 111 | // drop filter for seccomp option |
134 | int seccomp_filter_drop(int enforce_seccomp) { | 112 | int seccomp_filter_drop(int enforce_seccomp) { |
135 | // default seccomp | 113 | // default seccomp |
@@ -140,20 +118,7 @@ int seccomp_filter_drop(int enforce_seccomp) { | |||
140 | #if defined(__i386__) | 118 | #if defined(__i386__) |
141 | seccomp_filter_64(); | 119 | seccomp_filter_64(); |
142 | #endif | 120 | #endif |
143 | if (arg_debug) | ||
144 | printf("Build default seccomp filter\n"); | ||
145 | // build the seccomp filter as a regular user | ||
146 | int rv; | ||
147 | if (arg_allow_debuggers) | ||
148 | rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4, | ||
149 | PATH_FSECCOMP, "default", RUN_SECCOMP_CFG, "allow-debuggers"); | ||
150 | else | ||
151 | rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 3, | ||
152 | PATH_FSECCOMP, "default", RUN_SECCOMP_CFG); | ||
153 | if (rv) | ||
154 | exit(rv); | ||
155 | } | 121 | } |
156 | |||
157 | // default seccomp filter with additional drop list | 122 | // default seccomp filter with additional drop list |
158 | else if (cfg.seccomp_list && cfg.seccomp_list_drop == NULL) { | 123 | else if (cfg.seccomp_list && cfg.seccomp_list_drop == NULL) { |
159 | #if defined(__x86_64__) | 124 | #if defined(__x86_64__) |
@@ -208,7 +173,7 @@ int seccomp_filter_drop(int enforce_seccomp) { | |||
208 | exit(1); | 173 | exit(1); |
209 | } | 174 | } |
210 | 175 | ||
211 | if (arg_debug) | 176 | if (arg_debug && access(PATH_FSECCOMP, X_OK) == 0) |
212 | sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 3, | 177 | sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 3, |
213 | PATH_FSECCOMP, "print", RUN_SECCOMP_CFG); | 178 | PATH_FSECCOMP, "print", RUN_SECCOMP_CFG); |
214 | 179 | ||
diff --git a/src/fseccomp/main.c b/src/fseccomp/main.c index 2f85a786b..471e0b193 100644 --- a/src/fseccomp/main.c +++ b/src/fseccomp/main.c | |||
@@ -38,7 +38,7 @@ static void usage(void) { | |||
38 | } | 38 | } |
39 | 39 | ||
40 | int main(int argc, char **argv) { | 40 | int main(int argc, char **argv) { |
41 | #if 0 | 41 | //#if 0 |
42 | { | 42 | { |
43 | //system("cat /proc/self/status"); | 43 | //system("cat /proc/self/status"); |
44 | int i; | 44 | int i; |
@@ -46,7 +46,7 @@ for (i = 0; i < argc; i++) | |||
46 | printf("*%s* ", argv[i]); | 46 | printf("*%s* ", argv[i]); |
47 | printf("\n"); | 47 | printf("\n"); |
48 | } | 48 | } |
49 | #endif | 49 | //#endif |
50 | if (argc < 2) { | 50 | if (argc < 2) { |
51 | usage(); | 51 | usage(); |
52 | return 1; | 52 | return 1; |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index bb9ae270c..8441f25d5 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -1341,6 +1341,10 @@ both 32-bit and 64-bit filters are installed. | |||
1341 | .br | 1341 | .br |
1342 | 1342 | ||
1343 | .br | 1343 | .br |
1344 | Firejail will print seccomp violations to the audit log if the kernel was compiled with audit support (CONFIG_AUDIT flag). | ||
1345 | .br | ||
1346 | |||
1347 | .br | ||
1344 | Example: | 1348 | Example: |
1345 | .br | 1349 | .br |
1346 | $ firejail \-\-seccomp | 1350 | $ firejail \-\-seccomp |