diff options
author | netblue30 <netblue30@protonmail.com> | 2021-10-09 14:02:29 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-09 14:02:29 +0000 |
commit | 4937f73ca58976e40e7629deea57bce5935ba043 (patch) | |
tree | 490ce253fa8c6836f87f141da46512bd3f848bc0 /src | |
parent | s/S_IWRITE/S_IWUSR/ (diff) | |
parent | Merge pull request #4583 from kmk3/fix-include-limits-h (diff) | |
download | firejail-4937f73ca58976e40e7629deea57bce5935ba043.tar.gz firejail-4937f73ca58976e40e7629deea57bce5935ba043.tar.zst firejail-4937f73ca58976e40e7629deea57bce5935ba043.zip |
Merge branch 'master' into replace-iwrite-iwuser
Diffstat (limited to 'src')
-rw-r--r-- | src/fbuilder/build_fs.c | 8 | ||||
-rw-r--r-- | src/fbuilder/build_home.c | 4 | ||||
-rw-r--r-- | src/fbuilder/build_profile.c | 2 | ||||
-rw-r--r-- | src/firecfg/firecfg.config | 1 | ||||
-rw-r--r-- | src/firejail/checkcfg.c | 2 | ||||
-rw-r--r-- | src/firejail/env.c | 1 | ||||
-rw-r--r-- | src/firejail/firejail.h | 7 | ||||
-rw-r--r-- | src/firejail/fs.c | 39 | ||||
-rw-r--r-- | src/firejail/fs_dev.c | 1 | ||||
-rw-r--r-- | src/firejail/fs_home.c | 1 | ||||
-rw-r--r-- | src/firejail/fs_hostname.c | 1 | ||||
-rw-r--r-- | src/firejail/fs_trace.c | 32 | ||||
-rw-r--r-- | src/firejail/fs_var.c | 1 | ||||
-rw-r--r-- | src/firejail/main.c | 3 | ||||
-rw-r--r-- | src/firejail/mountinfo.c | 71 | ||||
-rw-r--r-- | src/firejail/profile.c | 15 | ||||
-rw-r--r-- | src/firejail/restrict_users.c | 1 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 11 | ||||
-rw-r--r-- | src/man/firejail-profile.txt | 2 |
19 files changed, 117 insertions, 86 deletions
diff --git a/src/fbuilder/build_fs.c b/src/fbuilder/build_fs.c index 019c3ac5a..8700e0ba1 100644 --- a/src/fbuilder/build_fs.c +++ b/src/fbuilder/build_fs.c | |||
@@ -182,12 +182,12 @@ static void var_callback(char *ptr) { | |||
182 | void build_var(const char *fname, FILE *fp) { | 182 | void build_var(const char *fname, FILE *fp) { |
183 | assert(fname); | 183 | assert(fname); |
184 | 184 | ||
185 | var_skip = filedb_load_whitelist(var_skip, "whitelist-var-common.inc", "allow /var/"); | 185 | var_skip = filedb_load_whitelist(var_skip, "whitelist-var-common.inc", "whitelist /var/"); |
186 | process_files(fname, "/var", var_callback); | 186 | process_files(fname, "/var", var_callback); |
187 | 187 | ||
188 | // always whitelist /var | 188 | // always whitelist /var |
189 | if (var_out) | 189 | if (var_out) |
190 | filedb_print(var_out, "allow /var/", fp); | 190 | filedb_print(var_out, "whitelist /var/", fp); |
191 | fprintf(fp, "include whitelist-var-common.inc\n"); | 191 | fprintf(fp, "include whitelist-var-common.inc\n"); |
192 | } | 192 | } |
193 | 193 | ||
@@ -222,12 +222,12 @@ static void share_callback(char *ptr) { | |||
222 | void build_share(const char *fname, FILE *fp) { | 222 | void build_share(const char *fname, FILE *fp) { |
223 | assert(fname); | 223 | assert(fname); |
224 | 224 | ||
225 | share_skip = filedb_load_whitelist(share_skip, "whitelist-usr-share-common.inc", "allow /usr/share/"); | 225 | share_skip = filedb_load_whitelist(share_skip, "whitelist-usr-share-common.inc", "whitelist /usr/share/"); |
226 | process_files(fname, "/usr/share", share_callback); | 226 | process_files(fname, "/usr/share", share_callback); |
227 | 227 | ||
228 | // always whitelist /usr/share | 228 | // always whitelist /usr/share |
229 | if (share_out) | 229 | if (share_out) |
230 | filedb_print(share_out, "allow /usr/share/", fp); | 230 | filedb_print(share_out, "whitelist /usr/share/", fp); |
231 | fprintf(fp, "include whitelist-usr-share-common.inc\n"); | 231 | fprintf(fp, "include whitelist-usr-share-common.inc\n"); |
232 | } | 232 | } |
233 | 233 | ||
diff --git a/src/fbuilder/build_home.c b/src/fbuilder/build_home.c index c85474779..0fe0ffef6 100644 --- a/src/fbuilder/build_home.c +++ b/src/fbuilder/build_home.c | |||
@@ -140,7 +140,7 @@ void build_home(const char *fname, FILE *fp) { | |||
140 | assert(fname); | 140 | assert(fname); |
141 | 141 | ||
142 | // load whitelist common | 142 | // load whitelist common |
143 | db_skip = filedb_load_whitelist(db_skip, "whitelist-common.inc", "allow ${HOME}/"); | 143 | db_skip = filedb_load_whitelist(db_skip, "whitelist-common.inc", "whitelist ${HOME}/"); |
144 | 144 | ||
145 | // find user home directory | 145 | // find user home directory |
146 | struct passwd *pw = getpwuid(getuid()); | 146 | struct passwd *pw = getpwuid(getuid()); |
@@ -168,7 +168,7 @@ void build_home(const char *fname, FILE *fp) { | |||
168 | 168 | ||
169 | // print the out list if any | 169 | // print the out list if any |
170 | if (db_out) { | 170 | if (db_out) { |
171 | filedb_print(db_out, "allow ${HOME}/", fp); | 171 | filedb_print(db_out, "whitelist ${HOME}/", fp); |
172 | fprintf(fp, "include whitelist-common.inc\n"); | 172 | fprintf(fp, "include whitelist-common.inc\n"); |
173 | } | 173 | } |
174 | else | 174 | else |
diff --git a/src/fbuilder/build_profile.c b/src/fbuilder/build_profile.c index 0b9a99739..c945d7253 100644 --- a/src/fbuilder/build_profile.c +++ b/src/fbuilder/build_profile.c | |||
@@ -92,7 +92,7 @@ void build_profile(int argc, char **argv, int index, FILE *fp) { | |||
92 | 92 | ||
93 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { | 93 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { |
94 | if (fp == stdout) | 94 | if (fp == stdout) |
95 | printf("--- Built profile beings after this line ---\n"); | 95 | printf("--- Built profile begins after this line ---\n"); |
96 | fprintf(fp, "# Save this file as \"application.profile\" (change \"application\" with the\n"); | 96 | fprintf(fp, "# Save this file as \"application.profile\" (change \"application\" with the\n"); |
97 | fprintf(fp, "# program name) in ~/.config/firejail directory. Firejail will find it\n"); | 97 | fprintf(fp, "# program name) in ~/.config/firejail directory. Firejail will find it\n"); |
98 | fprintf(fp, "# automatically every time you sandbox your application.\n#\n"); | 98 | fprintf(fp, "# automatically every time you sandbox your application.\n#\n"); |
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config index a544e25f2..aad22ec7a 100644 --- a/src/firecfg/firecfg.config +++ b/src/firecfg/firecfg.config | |||
@@ -151,6 +151,7 @@ clocks | |||
151 | cmus | 151 | cmus |
152 | code | 152 | code |
153 | code-oss | 153 | code-oss |
154 | codium | ||
154 | cola | 155 | cola |
155 | colorful | 156 | colorful |
156 | com.github.bleakgrey.tootle | 157 | com.github.bleakgrey.tootle |
diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c index 06e6f0ccb..e5d837bbb 100644 --- a/src/firejail/checkcfg.c +++ b/src/firejail/checkcfg.c | |||
@@ -58,6 +58,7 @@ int checkcfg(int val) { | |||
58 | cfg_val[CFG_XPRA_ATTACH] = 0; | 58 | cfg_val[CFG_XPRA_ATTACH] = 0; |
59 | cfg_val[CFG_SECCOMP_ERROR_ACTION] = -1; | 59 | cfg_val[CFG_SECCOMP_ERROR_ACTION] = -1; |
60 | cfg_val[CFG_BROWSER_ALLOW_DRM] = 0; | 60 | cfg_val[CFG_BROWSER_ALLOW_DRM] = 0; |
61 | cfg_val[CFG_ALLOW_TRAY] = 0; | ||
61 | 62 | ||
62 | // open configuration file | 63 | // open configuration file |
63 | const char *fname = SYSCONFDIR "/firejail.config"; | 64 | const char *fname = SYSCONFDIR "/firejail.config"; |
@@ -122,6 +123,7 @@ int checkcfg(int val) { | |||
122 | PARSE_YESNO(CFG_XPRA_ATTACH, "xpra-attach") | 123 | PARSE_YESNO(CFG_XPRA_ATTACH, "xpra-attach") |
123 | PARSE_YESNO(CFG_BROWSER_DISABLE_U2F, "browser-disable-u2f") | 124 | PARSE_YESNO(CFG_BROWSER_DISABLE_U2F, "browser-disable-u2f") |
124 | PARSE_YESNO(CFG_BROWSER_ALLOW_DRM, "browser-allow-drm") | 125 | PARSE_YESNO(CFG_BROWSER_ALLOW_DRM, "browser-allow-drm") |
126 | PARSE_YESNO(CFG_ALLOW_TRAY, "allow-tray") | ||
125 | #undef PARSE_YESNO | 127 | #undef PARSE_YESNO |
126 | 128 | ||
127 | // netfilter | 129 | // netfilter |
diff --git a/src/firejail/env.c b/src/firejail/env.c index ad16de037..4c0d729a1 100644 --- a/src/firejail/env.c +++ b/src/firejail/env.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <sys/stat.h> | 22 | #include <sys/stat.h> |
23 | #include <unistd.h> | 23 | #include <unistd.h> |
24 | #include <dirent.h> | 24 | #include <dirent.h> |
25 | #include <limits.h> | ||
25 | 26 | ||
26 | typedef struct env_t { | 27 | typedef struct env_t { |
27 | struct env_t *next; | 28 | struct env_t *next; |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 2a7d88575..bf51a4c93 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "../include/common.h" | 22 | #include "../include/common.h" |
23 | #include "../include/euid_common.h" | 23 | #include "../include/euid_common.h" |
24 | #include "../include/rundefs.h" | 24 | #include "../include/rundefs.h" |
25 | #include <linux/limits.h> // Note: Plain limits.h may break ARG_MAX (see #4583) | ||
25 | #include <stdarg.h> | 26 | #include <stdarg.h> |
26 | #include <sys/stat.h> | 27 | #include <sys/stat.h> |
27 | 28 | ||
@@ -563,7 +564,7 @@ typedef struct { | |||
563 | 564 | ||
564 | // mountinfo.c | 565 | // mountinfo.c |
565 | MountData *get_last_mount(void); | 566 | MountData *get_last_mount(void); |
566 | int get_mount_id(const char *path); | 567 | int get_mount_id(int fd); |
567 | char **build_mount_array(const int mount_id, const char *path); | 568 | char **build_mount_array(const int mount_id, const char *path); |
568 | 569 | ||
569 | // fs_var.c | 570 | // fs_var.c |
@@ -621,7 +622,8 @@ void caps_print_filter(pid_t pid) __attribute__((noreturn)); | |||
621 | void caps_drop_dac_override(void); | 622 | void caps_drop_dac_override(void); |
622 | 623 | ||
623 | // fs_trace.c | 624 | // fs_trace.c |
624 | void fs_trace_preload(void); | 625 | void fs_trace_touch_preload(void); |
626 | void fs_trace_touch_or_store_preload(void); | ||
625 | void fs_tracefile(void); | 627 | void fs_tracefile(void); |
626 | void fs_trace(void); | 628 | void fs_trace(void); |
627 | 629 | ||
@@ -801,6 +803,7 @@ enum { | |||
801 | CFG_NAME_CHANGE, | 803 | CFG_NAME_CHANGE, |
802 | CFG_SECCOMP_ERROR_ACTION, | 804 | CFG_SECCOMP_ERROR_ACTION, |
803 | // CFG_FILE_COPY_LIMIT - file copy limit handled using setenv/getenv | 805 | // CFG_FILE_COPY_LIMIT - file copy limit handled using setenv/getenv |
806 | CFG_ALLOW_TRAY, | ||
804 | CFG_MAX // this should always be the last entry | 807 | CFG_MAX // this should always be the last entry |
805 | }; | 808 | }; |
806 | extern char *xephyr_screen; | 809 | extern char *xephyr_screen; |
diff --git a/src/firejail/fs.c b/src/firejail/fs.c index 6d01b5e5d..1a9a8df0d 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <sys/stat.h> | 23 | #include <sys/stat.h> |
24 | #include <sys/statvfs.h> | 24 | #include <sys/statvfs.h> |
25 | #include <sys/wait.h> | 25 | #include <sys/wait.h> |
26 | #include <linux/limits.h> | ||
27 | #include <fnmatch.h> | 26 | #include <fnmatch.h> |
28 | #include <glob.h> | 27 | #include <glob.h> |
29 | #include <dirent.h> | 28 | #include <dirent.h> |
@@ -633,34 +632,30 @@ out: | |||
633 | } | 632 | } |
634 | 633 | ||
635 | // remount recursively; requires a resolved path | 634 | // remount recursively; requires a resolved path |
636 | static void fs_remount_rec(const char *dir, OPERATION op) { | 635 | static void fs_remount_rec(const char *path, OPERATION op) { |
637 | EUID_ASSERT(); | 636 | EUID_ASSERT(); |
638 | assert(dir); | 637 | assert(op < OPERATION_MAX); |
638 | assert(path); | ||
639 | 639 | ||
640 | struct stat s; | 640 | // no need to search /proc/self/mountinfo for submounts if not a directory |
641 | if (stat(dir, &s) != 0) | 641 | int fd = open(path, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
642 | return; | 642 | if (fd < 0) { |
643 | if (!S_ISDIR(s.st_mode)) { | 643 | fs_remount_simple(path, op); |
644 | // no need to search in /proc/self/mountinfo for submounts if not a directory | ||
645 | fs_remount_simple(dir, op); | ||
646 | return; | 644 | return; |
647 | } | 645 | } |
648 | // get mount point of the directory | 646 | |
649 | int mountid = get_mount_id(dir); | 647 | // get mount id of the directory |
650 | if (mountid == -1) | 648 | int mountid = get_mount_id(fd); |
651 | return; | 649 | close(fd); |
652 | if (mountid == -2) { | 650 | if (mountid < 0) { |
653 | // falling back to a simple remount on old kernels | 651 | // falling back to a simple remount |
654 | static int mount_warning = 0; | 652 | fwarning("%s %s not applied recursively\n", opstr[op], path); |
655 | if (!mount_warning) { | 653 | fs_remount_simple(path, op); |
656 | fwarning("read-only, read-write and noexec options are not applied recursively\n"); | ||
657 | mount_warning = 1; | ||
658 | } | ||
659 | fs_remount_simple(dir, op); | ||
660 | return; | 654 | return; |
661 | } | 655 | } |
656 | |||
662 | // build array with all mount points that need to get remounted | 657 | // build array with all mount points that need to get remounted |
663 | char **arr = build_mount_array(mountid, dir); | 658 | char **arr = build_mount_array(mountid, path); |
664 | assert(arr); | 659 | assert(arr); |
665 | // remount | 660 | // remount |
666 | char **tmp = arr; | 661 | char **tmp = arr; |
diff --git a/src/firejail/fs_dev.c b/src/firejail/fs_dev.c index a43b18344..694d0a379 100644 --- a/src/firejail/fs_dev.c +++ b/src/firejail/fs_dev.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include "firejail.h" | 20 | #include "firejail.h" |
21 | #include <sys/mount.h> | 21 | #include <sys/mount.h> |
22 | #include <sys/stat.h> | 22 | #include <sys/stat.h> |
23 | #include <linux/limits.h> | ||
24 | #include <glob.h> | 23 | #include <glob.h> |
25 | #include <dirent.h> | 24 | #include <dirent.h> |
26 | #include <fcntl.h> | 25 | #include <fcntl.h> |
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c index 590337da1..8d8530d81 100644 --- a/src/firejail/fs_home.c +++ b/src/firejail/fs_home.c | |||
@@ -19,7 +19,6 @@ | |||
19 | */ | 19 | */ |
20 | #include "firejail.h" | 20 | #include "firejail.h" |
21 | #include <sys/mount.h> | 21 | #include <sys/mount.h> |
22 | #include <linux/limits.h> | ||
23 | #include <dirent.h> | 22 | #include <dirent.h> |
24 | #include <errno.h> | 23 | #include <errno.h> |
25 | #include <sys/stat.h> | 24 | #include <sys/stat.h> |
diff --git a/src/firejail/fs_hostname.c b/src/firejail/fs_hostname.c index 43f6e658e..8b7e94f51 100644 --- a/src/firejail/fs_hostname.c +++ b/src/firejail/fs_hostname.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include "firejail.h" | 20 | #include "firejail.h" |
21 | #include <sys/mount.h> | 21 | #include <sys/mount.h> |
22 | #include <sys/stat.h> | 22 | #include <sys/stat.h> |
23 | #include <linux/limits.h> | ||
24 | #include <glob.h> | 23 | #include <glob.h> |
25 | #include <dirent.h> | 24 | #include <dirent.h> |
26 | #include <fcntl.h> | 25 | #include <fcntl.h> |
diff --git a/src/firejail/fs_trace.c b/src/firejail/fs_trace.c index dd9abe253..17a7b3d23 100644 --- a/src/firejail/fs_trace.c +++ b/src/firejail/fs_trace.c | |||
@@ -20,25 +20,31 @@ | |||
20 | #include "firejail.h" | 20 | #include "firejail.h" |
21 | #include <sys/mount.h> | 21 | #include <sys/mount.h> |
22 | #include <sys/stat.h> | 22 | #include <sys/stat.h> |
23 | #include <linux/limits.h> | ||
24 | #include <glob.h> | 23 | #include <glob.h> |
25 | #include <dirent.h> | 24 | #include <dirent.h> |
26 | #include <fcntl.h> | 25 | #include <fcntl.h> |
27 | #include <pwd.h> | 26 | #include <pwd.h> |
28 | 27 | ||
29 | void fs_trace_preload(void) { | 28 | // create an empty /etc/ld.so.preload |
29 | void fs_trace_touch_preload(void) { | ||
30 | create_empty_file_as_root("/etc/ld.so.preload", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | ||
31 | } | ||
32 | |||
33 | void fs_trace_touch_or_store_preload(void) { | ||
30 | struct stat s; | 34 | struct stat s; |
31 | 35 | ||
32 | // create an empty /etc/ld.so.preload | 36 | if (stat("/etc/ld.so.preload", &s) != 0) { |
33 | if (stat("/etc/ld.so.preload", &s)) { | 37 | fs_trace_touch_preload(); |
34 | if (arg_debug) | 38 | return; |
35 | printf("Creating an empty /etc/ld.so.preload file\n"); | 39 | } |
36 | FILE *fp = fopen("/etc/ld.so.preload", "wxe"); | 40 | |
37 | if (!fp) | 41 | if (s.st_size == 0) |
38 | errExit("fopen"); | 42 | return; |
39 | SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | 43 | |
40 | fclose(fp); | 44 | // create a copy of /etc/ld.so.preload |
41 | fs_logger("touch /etc/ld.so.preload"); | 45 | if (copy_file("/etc/ld.so.preload", RUN_LDPRELOAD_FILE, 0, 0, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) { |
46 | fprintf(stderr, "Error: cannot copy /etc/ld.so.preload file\n"); | ||
47 | exit(1); | ||
42 | } | 48 | } |
43 | } | 49 | } |
44 | 50 | ||
@@ -83,7 +89,7 @@ void fs_trace(void) { | |||
83 | if (arg_debug) | 89 | if (arg_debug) |
84 | printf("Create the new ld.so.preload file\n"); | 90 | printf("Create the new ld.so.preload file\n"); |
85 | 91 | ||
86 | FILE *fp = fopen(RUN_LDPRELOAD_FILE, "we"); | 92 | FILE *fp = fopen(RUN_LDPRELOAD_FILE, "ae"); |
87 | if (!fp) | 93 | if (!fp) |
88 | errExit("fopen"); | 94 | errExit("fopen"); |
89 | const char *prefix = RUN_FIREJAIL_LIB_DIR; | 95 | const char *prefix = RUN_FIREJAIL_LIB_DIR; |
diff --git a/src/firejail/fs_var.c b/src/firejail/fs_var.c index 12ffd8383..e19d0df96 100644 --- a/src/firejail/fs_var.c +++ b/src/firejail/fs_var.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include "firejail.h" | 20 | #include "firejail.h" |
21 | #include <sys/mount.h> | 21 | #include <sys/mount.h> |
22 | #include <sys/stat.h> | 22 | #include <sys/stat.h> |
23 | #include <linux/limits.h> | ||
24 | #include <glob.h> | 23 | #include <glob.h> |
25 | #include <dirent.h> | 24 | #include <dirent.h> |
26 | #include <fcntl.h> | 25 | #include <fcntl.h> |
diff --git a/src/firejail/main.c b/src/firejail/main.c index 81d148257..cc5186204 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -32,7 +32,8 @@ | |||
32 | #include <dirent.h> | 32 | #include <dirent.h> |
33 | #include <pwd.h> | 33 | #include <pwd.h> |
34 | #include <errno.h> | 34 | #include <errno.h> |
35 | //#include <limits.h> | 35 | |
36 | #include <limits.h> | ||
36 | #include <sys/file.h> | 37 | #include <sys/file.h> |
37 | #include <sys/prctl.h> | 38 | #include <sys/prctl.h> |
38 | #include <signal.h> | 39 | #include <signal.h> |
diff --git a/src/firejail/mountinfo.c b/src/firejail/mountinfo.c index 64a94bd84..304f80eee 100644 --- a/src/firejail/mountinfo.c +++ b/src/firejail/mountinfo.c | |||
@@ -19,6 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include "firejail.h" | 21 | #include "firejail.h" |
22 | #include <errno.h> | ||
22 | 23 | ||
23 | #include <fcntl.h> | 24 | #include <fcntl.h> |
24 | #ifndef O_PATH | 25 | #ifndef O_PATH |
@@ -151,53 +152,71 @@ MountData *get_last_mount(void) { | |||
151 | return &mdata; | 152 | return &mdata; |
152 | } | 153 | } |
153 | 154 | ||
154 | // Extract the mount id from /proc/self/fdinfo and return it. | 155 | // Returns mount id, or -1 if fd refers to a procfs or sysfs file |
155 | int get_mount_id(const char *path) { | 156 | static int get_mount_id_from_handle(int fd) { |
156 | EUID_ASSERT(); | 157 | EUID_ASSERT(); |
157 | assert(path); | ||
158 | 158 | ||
159 | int fd = open(path, O_PATH|O_CLOEXEC); | 159 | char *proc; |
160 | if (fd == -1) | 160 | if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1) |
161 | return -1; | 161 | errExit("asprintf"); |
162 | struct file_handle *fh = malloc(sizeof *fh); | ||
163 | if (!fh) | ||
164 | errExit("malloc"); | ||
165 | fh->handle_bytes = 0; | ||
166 | |||
167 | int rv = -1; | ||
168 | int tmp; | ||
169 | if (name_to_handle_at(-1, proc, fh, &tmp, AT_SYMLINK_FOLLOW) != -1) { | ||
170 | fprintf(stderr, "Error: unexpected result from name_to_handle_at\n"); | ||
171 | exit(1); | ||
172 | } | ||
173 | if (errno == EOVERFLOW && fh->handle_bytes) | ||
174 | rv = tmp; | ||
175 | |||
176 | free(proc); | ||
177 | free(fh); | ||
178 | return rv; | ||
179 | } | ||
180 | |||
181 | // Returns mount id, or -1 on kernels < 3.15 | ||
182 | static int get_mount_id_from_fdinfo(int fd) { | ||
183 | EUID_ASSERT(); | ||
184 | int rv = -1; | ||
162 | 185 | ||
163 | char *fdinfo; | 186 | char *proc; |
164 | if (asprintf(&fdinfo, "/proc/self/fdinfo/%d", fd) == -1) | 187 | if (asprintf(&proc, "/proc/self/fdinfo/%d", fd) == -1) |
165 | errExit("asprintf"); | 188 | errExit("asprintf"); |
166 | EUID_ROOT(); | 189 | EUID_ROOT(); |
167 | FILE *fp = fopen(fdinfo, "re"); | 190 | FILE *fp = fopen(proc, "re"); |
168 | EUID_USER(); | 191 | EUID_USER(); |
169 | free(fdinfo); | ||
170 | if (!fp) | 192 | if (!fp) |
171 | goto errexit; | 193 | goto errexit; |
172 | 194 | ||
173 | // read the file | ||
174 | char buf[MAX_BUF]; | 195 | char buf[MAX_BUF]; |
175 | if (fgets(buf, MAX_BUF, fp) == NULL) | 196 | while (fgets(buf, MAX_BUF, fp)) { |
176 | goto errexit; | ||
177 | do { | ||
178 | if (strncmp(buf, "mnt_id:", 7) == 0) { | 197 | if (strncmp(buf, "mnt_id:", 7) == 0) { |
179 | char *ptr = buf + 7; | 198 | if (sscanf(buf + 7, "%d", &rv) != 1) |
180 | while (*ptr != '\0' && (*ptr == ' ' || *ptr == '\t')) { | ||
181 | ptr++; | ||
182 | } | ||
183 | if (*ptr == '\0') | ||
184 | goto errexit; | 199 | goto errexit; |
185 | fclose(fp); | 200 | break; |
186 | close(fd); | ||
187 | return atoi(ptr); | ||
188 | } | 201 | } |
189 | } while (fgets(buf, MAX_BUF, fp)); | 202 | } |
190 | 203 | ||
191 | // fallback, kernels older than 3.15 don't expose the mount id in this place | 204 | free(proc); |
192 | fclose(fp); | 205 | fclose(fp); |
193 | close(fd); | 206 | return rv; |
194 | return -2; | ||
195 | 207 | ||
196 | errexit: | 208 | errexit: |
197 | fprintf(stderr, "Error: cannot read proc file\n"); | 209 | fprintf(stderr, "Error: cannot read proc file\n"); |
198 | exit(1); | 210 | exit(1); |
199 | } | 211 | } |
200 | 212 | ||
213 | int get_mount_id(int fd) { | ||
214 | int rv = get_mount_id_from_fdinfo(fd); | ||
215 | if (rv < 0) | ||
216 | rv = get_mount_id_from_handle(fd); | ||
217 | return rv; | ||
218 | } | ||
219 | |||
201 | // Check /proc/self/mountinfo if path contains any mounts points. | 220 | // Check /proc/self/mountinfo if path contains any mounts points. |
202 | // Returns an array that can be iterated over for recursive remounting. | 221 | // Returns an array that can be iterated over for recursive remounting. |
203 | char **build_mount_array(const int mount_id, const char *path) { | 222 | char **build_mount_array(const int mount_id, const char *path) { |
diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 059100fcb..5390249ea 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c | |||
@@ -175,6 +175,10 @@ static int check_allow_drm(void) { | |||
175 | return checkcfg(CFG_BROWSER_ALLOW_DRM) != 0; | 175 | return checkcfg(CFG_BROWSER_ALLOW_DRM) != 0; |
176 | } | 176 | } |
177 | 177 | ||
178 | static int check_allow_tray(void) { | ||
179 | return checkcfg(CFG_ALLOW_TRAY) != 0; | ||
180 | } | ||
181 | |||
178 | Cond conditionals[] = { | 182 | Cond conditionals[] = { |
179 | {"HAS_APPIMAGE", check_appimage}, | 183 | {"HAS_APPIMAGE", check_appimage}, |
180 | {"HAS_NET", check_netoptions}, | 184 | {"HAS_NET", check_netoptions}, |
@@ -184,6 +188,7 @@ Cond conditionals[] = { | |||
184 | {"HAS_X11", check_x11}, | 188 | {"HAS_X11", check_x11}, |
185 | {"BROWSER_DISABLE_U2F", check_disable_u2f}, | 189 | {"BROWSER_DISABLE_U2F", check_disable_u2f}, |
186 | {"BROWSER_ALLOW_DRM", check_allow_drm}, | 190 | {"BROWSER_ALLOW_DRM", check_allow_drm}, |
191 | {"ALLOW_TRAY", check_allow_tray}, | ||
187 | { NULL, NULL } | 192 | { NULL, NULL } |
188 | }; | 193 | }; |
189 | 194 | ||
@@ -630,7 +635,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
630 | #endif | 635 | #endif |
631 | return 0; | 636 | return 0; |
632 | } | 637 | } |
633 | else if (strncmp(ptr, "netns ", 6) == 0) { | 638 | else if (strncmp(ptr, "netns ", 6) == 0) { |
634 | #ifdef HAVE_NETWORK | 639 | #ifdef HAVE_NETWORK |
635 | if (checkcfg(CFG_NETWORK)) { | 640 | if (checkcfg(CFG_NETWORK)) { |
636 | arg_netns = ptr + 6; | 641 | arg_netns = ptr + 6; |
@@ -981,10 +986,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
981 | warning_feature_disabled("seccomp"); | 986 | warning_feature_disabled("seccomp"); |
982 | return 0; | 987 | return 0; |
983 | } | 988 | } |
984 | if (strncmp(ptr, "seccomp.32.drop ", 13) == 0) { | 989 | if (strncmp(ptr, "seccomp.32.drop ", 16) == 0) { |
985 | if (checkcfg(CFG_SECCOMP)) { | 990 | if (checkcfg(CFG_SECCOMP)) { |
986 | arg_seccomp32 = 1; | 991 | arg_seccomp32 = 1; |
987 | cfg.seccomp_list_drop32 = seccomp_check_list(ptr + 13); | 992 | cfg.seccomp_list_drop32 = seccomp_check_list(ptr + 16); |
988 | } | 993 | } |
989 | else | 994 | else |
990 | warning_feature_disabled("seccomp"); | 995 | warning_feature_disabled("seccomp"); |
@@ -1001,10 +1006,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
1001 | warning_feature_disabled("seccomp"); | 1006 | warning_feature_disabled("seccomp"); |
1002 | return 0; | 1007 | return 0; |
1003 | } | 1008 | } |
1004 | if (strncmp(ptr, "seccomp.32.keep ", 13) == 0) { | 1009 | if (strncmp(ptr, "seccomp.32.keep ", 16) == 0) { |
1005 | if (checkcfg(CFG_SECCOMP)) { | 1010 | if (checkcfg(CFG_SECCOMP)) { |
1006 | arg_seccomp32 = 1; | 1011 | arg_seccomp32 = 1; |
1007 | cfg.seccomp_list_keep32 = seccomp_check_list(ptr + 13); | 1012 | cfg.seccomp_list_keep32 = seccomp_check_list(ptr + 16); |
1008 | } | 1013 | } |
1009 | else | 1014 | else |
1010 | warning_feature_disabled("seccomp"); | 1015 | warning_feature_disabled("seccomp"); |
diff --git a/src/firejail/restrict_users.c b/src/firejail/restrict_users.c index 6f17231a4..59077dada 100644 --- a/src/firejail/restrict_users.c +++ b/src/firejail/restrict_users.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include "../include/firejail_user.h" | 21 | #include "../include/firejail_user.h" |
22 | #include <sys/mount.h> | 22 | #include <sys/mount.h> |
23 | #include <sys/stat.h> | 23 | #include <sys/stat.h> |
24 | #include <linux/limits.h> | ||
25 | #include <fnmatch.h> | 24 | #include <fnmatch.h> |
26 | #include <glob.h> | 25 | #include <glob.h> |
27 | #include <dirent.h> | 26 | #include <dirent.h> |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 5e0e849b9..d66b6c573 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -798,7 +798,7 @@ int sandbox(void* sandbox_arg) { | |||
798 | 798 | ||
799 | // trace pre-install | 799 | // trace pre-install |
800 | if (need_preload) | 800 | if (need_preload) |
801 | fs_trace_preload(); | 801 | fs_trace_touch_or_store_preload(); |
802 | 802 | ||
803 | // store hosts file | 803 | // store hosts file |
804 | if (cfg.hosts_file) | 804 | if (cfg.hosts_file) |
@@ -814,8 +814,11 @@ int sandbox(void* sandbox_arg) { | |||
814 | //**************************** | 814 | //**************************** |
815 | // trace pre-install, this time inside chroot | 815 | // trace pre-install, this time inside chroot |
816 | //**************************** | 816 | //**************************** |
817 | if (need_preload) | 817 | if (need_preload) { |
818 | fs_trace_preload(); | 818 | int rv = unlink(RUN_LDPRELOAD_FILE); |
819 | (void) rv; | ||
820 | fs_trace_touch_or_store_preload(); | ||
821 | } | ||
819 | } | 822 | } |
820 | else | 823 | else |
821 | #endif | 824 | #endif |
@@ -992,7 +995,7 @@ int sandbox(void* sandbox_arg) { | |||
992 | 995 | ||
993 | // create /etc/ld.so.preload file again | 996 | // create /etc/ld.so.preload file again |
994 | if (need_preload) | 997 | if (need_preload) |
995 | fs_trace_preload(); | 998 | fs_trace_touch_preload(); |
996 | 999 | ||
997 | // openSUSE configuration is split between /etc and /usr/etc | 1000 | // openSUSE configuration is split between /etc and /usr/etc |
998 | // process private-etc a second time | 1001 | // process private-etc a second time |
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt index a76fd3765..a1eccaa5e 100644 --- a/src/man/firejail-profile.txt +++ b/src/man/firejail-profile.txt | |||
@@ -174,7 +174,7 @@ Example: "?HAS_APPIMAGE: whitelist ${HOME}/special/appimage/dir" | |||
174 | 174 | ||
175 | This example will load the whitelist profile line only if the \-\-appimage option has been specified on the command line. | 175 | This example will load the whitelist profile line only if the \-\-appimage option has been specified on the command line. |
176 | 176 | ||
177 | Currently the only conditionals supported this way are HAS_APPIMAGE, HAS_NET, HAS_NODBUS, HAS_NOSOUND, HAS_PRIVATE and HAS_X11. The conditionals BROWSER_DISABLE_U2F and BROWSER_ALLOW_DRM | 177 | Currently the only conditionals supported this way are HAS_APPIMAGE, HAS_NET, HAS_NODBUS, HAS_NOSOUND, HAS_PRIVATE and HAS_X11. The conditionals ALLOW_TRAY, BROWSER_DISABLE_U2F and BROWSER_ALLOW_DRM |
178 | can be enabled or disabled globally in Firejail's configuration file. | 178 | can be enabled or disabled globally in Firejail's configuration file. |
179 | 179 | ||
180 | The profile line may be any profile line that you would normally use in a profile \fBexcept\fR for "quiet" and "include" lines. | 180 | The profile line may be any profile line that you would normally use in a profile \fBexcept\fR for "quiet" and "include" lines. |