diff options
-rw-r--r-- | etc/disable-devel.inc | 3 | ||||
-rw-r--r-- | etc/start-tor-browser.profile | 2 | ||||
-rw-r--r-- | etc/torbrowser-launcher.profile | 2 | ||||
-rw-r--r-- | src/firejail/join.c | 3 | ||||
-rw-r--r-- | src/firejail/macros.c | 1 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 2 | ||||
-rw-r--r-- | src/firejail/util.c | 59 |
7 files changed, 38 insertions, 34 deletions
diff --git a/etc/disable-devel.inc b/etc/disable-devel.inc index 0327e717e..627856803 100644 --- a/etc/disable-devel.inc +++ b/etc/disable-devel.inc | |||
@@ -26,7 +26,8 @@ blacklist /usr/include | |||
26 | blacklist ${PATH}/clang* | 26 | blacklist ${PATH}/clang* |
27 | blacklist ${PATH}/lldb* | 27 | blacklist ${PATH}/lldb* |
28 | blacklist ${PATH}/llvm* | 28 | blacklist ${PATH}/llvm* |
29 | blacklist /usr/lib/llvm* | 29 | # see issue #2106 - it disables hardware acceleration in Firefox on Radeon GPU |
30 | # blacklist /usr/lib/llvm* | ||
30 | 31 | ||
31 | # tcc - Tiny C Compiler | 32 | # tcc - Tiny C Compiler |
32 | blacklist ${PATH}/tcc | 33 | blacklist ${PATH}/tcc |
diff --git a/etc/start-tor-browser.profile b/etc/start-tor-browser.profile index 6069c5174..4d9ebcb2e 100644 --- a/etc/start-tor-browser.profile +++ b/etc/start-tor-browser.profile | |||
@@ -28,7 +28,7 @@ protocol unix,inet,inet6 | |||
28 | seccomp.drop @clock,@cpu-emulation,@debug,@module,@obsolete,@raw-io,@reboot,@resources,@swap,acct,add_key,bpf,fanotify_init,io_cancel,io_destroy,io_getevents,io_setup,io_submit,ioprio_set,kcmp,keyctl,mount,name_to_handle_at,nfsservctl,ni_syscall,open_by_handle_at,personality,pivot_root,process_vm_readv,ptrace,remap_file_pages,request_key,setdomainname,sethostname,syslog,umount,umount2,userfaultfd,vhangup,vmsplice | 28 | seccomp.drop @clock,@cpu-emulation,@debug,@module,@obsolete,@raw-io,@reboot,@resources,@swap,acct,add_key,bpf,fanotify_init,io_cancel,io_destroy,io_getevents,io_setup,io_submit,ioprio_set,kcmp,keyctl,mount,name_to_handle_at,nfsservctl,ni_syscall,open_by_handle_at,personality,pivot_root,process_vm_readv,ptrace,remap_file_pages,request_key,setdomainname,sethostname,syslog,umount,umount2,userfaultfd,vhangup,vmsplice |
29 | shell none | 29 | shell none |
30 | # tracelog may cause issues, see github issue #1930 | 30 | # tracelog may cause issues, see github issue #1930 |
31 | tracelog | 31 | #tracelog |
32 | 32 | ||
33 | disable-mnt | 33 | disable-mnt |
34 | private-bin bash,sh,grep,tail,env,gpg,id,readlink,dirname,test,mkdir,ln,sed,cp,rm,getconf | 34 | private-bin bash,sh,grep,tail,env,gpg,id,readlink,dirname,test,mkdir,ln,sed,cp,rm,getconf |
diff --git a/etc/torbrowser-launcher.profile b/etc/torbrowser-launcher.profile index f175b6590..307377acc 100644 --- a/etc/torbrowser-launcher.profile +++ b/etc/torbrowser-launcher.profile | |||
@@ -43,7 +43,7 @@ protocol unix,inet,inet6 | |||
43 | seccomp.drop @clock,@cpu-emulation,@debug,@module,@obsolete,@raw-io,@reboot,@resources,@swap,acct,add_key,bpf,fanotify_init,io_cancel,io_destroy,io_getevents,io_setup,io_submit,ioprio_set,kcmp,keyctl,mount,name_to_handle_at,nfsservctl,ni_syscall,open_by_handle_at,personality,pivot_root,process_vm_readv,ptrace,remap_file_pages,request_key,setdomainname,sethostname,syslog,umount,umount2,userfaultfd,vhangup,vmsplice | 43 | seccomp.drop @clock,@cpu-emulation,@debug,@module,@obsolete,@raw-io,@reboot,@resources,@swap,acct,add_key,bpf,fanotify_init,io_cancel,io_destroy,io_getevents,io_setup,io_submit,ioprio_set,kcmp,keyctl,mount,name_to_handle_at,nfsservctl,ni_syscall,open_by_handle_at,personality,pivot_root,process_vm_readv,ptrace,remap_file_pages,request_key,setdomainname,sethostname,syslog,umount,umount2,userfaultfd,vhangup,vmsplice |
44 | shell none | 44 | shell none |
45 | # tracelog may cause issues, see github issue #1930 | 45 | # tracelog may cause issues, see github issue #1930 |
46 | tracelog | 46 | #tracelog |
47 | 47 | ||
48 | disable-mnt | 48 | disable-mnt |
49 | private-bin bash,cp,dirname,env,expr,file,getconf,gpg,grep,id,ln,mkdir,python*,readlink,rm,sed,sh,tail,tar,tclsh,test,tor-browser-en,torbrowser-launcher,xz | 49 | private-bin bash,cp,dirname,env,expr,file,getconf,gpg,grep,id,ln,mkdir,python*,readlink,rm,sed,sh,tail,tar,tclsh,test,tor-browser-en,torbrowser-launcher,xz |
diff --git a/src/firejail/join.c b/src/firejail/join.c index b22a6e054..569cfcff7 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c | |||
@@ -333,6 +333,7 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
333 | caps_set(caps); | 333 | caps_set(caps); |
334 | } | 334 | } |
335 | 335 | ||
336 | EUID_USER(); | ||
336 | // set nice | 337 | // set nice |
337 | if (arg_nice) { | 338 | if (arg_nice) { |
338 | errno = 0; | 339 | errno = 0; |
@@ -345,8 +346,6 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
345 | } | 346 | } |
346 | 347 | ||
347 | // set environment, add x11 display | 348 | // set environment, add x11 display |
348 | EUID_USER(); | ||
349 | |||
350 | env_defaults(); | 349 | env_defaults(); |
351 | if (display) { | 350 | if (display) { |
352 | char *display_str; | 351 | char *display_str; |
diff --git a/src/firejail/macros.c b/src/firejail/macros.c index 283de57f2..27893938f 100644 --- a/src/firejail/macros.c +++ b/src/firejail/macros.c | |||
@@ -92,6 +92,7 @@ int is_macro(const char *name) { | |||
92 | 92 | ||
93 | // returns mallocated memory | 93 | // returns mallocated memory |
94 | static char *resolve_xdg(const char *var) { | 94 | static char *resolve_xdg(const char *var) { |
95 | EUID_ASSERT(); | ||
95 | char *fname; | 96 | char *fname; |
96 | struct stat s; | 97 | struct stat s; |
97 | size_t length = strlen(var); | 98 | size_t length = strlen(var); |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 3e22e5a53..f9be62a79 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -882,7 +882,6 @@ int sandbox(void* sandbox_arg) { | |||
882 | } | 882 | } |
883 | } | 883 | } |
884 | 884 | ||
885 | EUID_ROOT(); | ||
886 | // set nice | 885 | // set nice |
887 | if (arg_nice) { | 886 | if (arg_nice) { |
888 | errno = 0; | 887 | errno = 0; |
@@ -893,6 +892,7 @@ int sandbox(void* sandbox_arg) { | |||
893 | errno = 0; | 892 | errno = 0; |
894 | } | 893 | } |
895 | } | 894 | } |
895 | EUID_ROOT(); | ||
896 | 896 | ||
897 | //**************************** | 897 | //**************************** |
898 | // set security filters | 898 | // set security filters |
diff --git a/src/firejail/util.c b/src/firejail/util.c index ff2bceacd..4a164901d 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | #define MAX_GROUPS 1024 | 34 | #define MAX_GROUPS 1024 |
35 | #define MAXBUF 4098 | 35 | #define MAXBUF 4098 |
36 | 36 | #define EMPTY_STRING ("") | |
37 | 37 | ||
38 | 38 | ||
39 | // send the error to /var/log/auth.log and exit after a small delay | 39 | // send the error to /var/log/auth.log and exit after a small delay |
@@ -1049,7 +1049,7 @@ void disable_file_path(const char *path, const char *file) { | |||
1049 | } | 1049 | } |
1050 | 1050 | ||
1051 | // The returned file descriptor should be suitable for privileged operations on | 1051 | // The returned file descriptor should be suitable for privileged operations on |
1052 | // user controlled paths. Passed flags are ignored if path is a top level directory. | 1052 | // user controlled paths |
1053 | int safe_fd(const char *path, int flags) { | 1053 | int safe_fd(const char *path, int flags) { |
1054 | assert(path); | 1054 | assert(path); |
1055 | 1055 | ||
@@ -1059,13 +1059,7 @@ int safe_fd(const char *path, int flags) { | |||
1059 | // reject ".." | 1059 | // reject ".." |
1060 | if (strstr(path, "..")) | 1060 | if (strstr(path, "..")) |
1061 | goto errexit; | 1061 | goto errexit; |
1062 | 1062 | char *p = strrchr(path, '/'); | |
1063 | // work with a copy of path | ||
1064 | char *dup = strdup(path); | ||
1065 | if (dup == NULL) | ||
1066 | errExit("strdup"); | ||
1067 | |||
1068 | char *p = strrchr(dup, '/'); | ||
1069 | assert(p); | 1063 | assert(p); |
1070 | // reject trailing slash, root directory | 1064 | // reject trailing slash, root directory |
1071 | if (*(p + 1) == '\0') | 1065 | if (*(p + 1) == '\0') |
@@ -1073,45 +1067,54 @@ int safe_fd(const char *path, int flags) { | |||
1073 | // reject trailing dot | 1067 | // reject trailing dot |
1074 | if (*(p + 1) == '.' && *(p + 2) == '\0') | 1068 | if (*(p + 1) == '.' && *(p + 2) == '\0') |
1075 | goto errexit; | 1069 | goto errexit; |
1076 | // if there is more than one path segment, keep the last one for later | 1070 | |
1077 | if (p != dup) | 1071 | // work with a copy of path |
1078 | *p = '\0'; | 1072 | char *dup = strdup(path); |
1073 | if (!dup) | ||
1074 | errExit("strdup"); | ||
1079 | 1075 | ||
1080 | int parentfd = open("/", O_PATH|O_DIRECTORY|O_CLOEXEC); | 1076 | int parentfd = open("/", O_PATH|O_DIRECTORY|O_CLOEXEC); |
1081 | if (parentfd == -1) | 1077 | if (parentfd == -1) |
1082 | errExit("open"); | 1078 | errExit("open"); |
1083 | 1079 | ||
1084 | // traverse the path and return -1 if a symlink is encountered | 1080 | // traverse the path and return -1 if a symlink is encountered |
1085 | int weird_pathname = 1; | ||
1086 | int fd = -1; | 1081 | int fd = -1; |
1082 | char *current_tok = EMPTY_STRING; | ||
1087 | char *tok = strtok(dup, "/"); | 1083 | char *tok = strtok(dup, "/"); |
1084 | assert(tok); | ||
1088 | while (tok) { | 1085 | while (tok) { |
1089 | // skip all "/./" | 1086 | // skip all "/./" |
1090 | if (strcmp(tok, ".") == 0) { | 1087 | if (strcmp(tok, ".") == 0) { |
1091 | tok = strtok(NULL, "/"); | 1088 | tok = strtok(NULL, "/"); |
1092 | continue; | 1089 | continue; |
1093 | } | 1090 | } |
1094 | weird_pathname = 0; | 1091 | // open the element, assuming it is a directory; this fails with ENOTDIR if it is a symbolic link |
1095 | |||
1096 | // open the directory | ||
1097 | fd = openat(parentfd, tok, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 1092 | fd = openat(parentfd, tok, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
1098 | close(parentfd); | ||
1099 | if (fd == -1) { | 1093 | if (fd == -1) { |
1094 | // if the following token is NULL, the current token is the final path element | ||
1095 | // try again to open it, this time using the passed flags, and return -1 or the descriptor | ||
1096 | current_tok = tok; | ||
1097 | tok = strtok(NULL, "/"); | ||
1098 | if (!tok) | ||
1099 | fd = openat(parentfd, current_tok, flags|O_NOFOLLOW); | ||
1100 | close(parentfd); | ||
1100 | free(dup); | 1101 | free(dup); |
1101 | return -1; | 1102 | return fd; // -1 if open failed |
1102 | } | 1103 | } |
1103 | 1104 | // move on to next path segment | |
1104 | parentfd = fd; | 1105 | current_tok = tok; |
1105 | tok = strtok(NULL, "/"); | 1106 | tok = strtok(NULL, "/"); |
1107 | if (tok) { | ||
1108 | close(parentfd); | ||
1109 | parentfd = fd; | ||
1110 | } | ||
1106 | } | 1111 | } |
1107 | if (p != dup) { | 1112 | |
1108 | // consistent flags for top level directories (////foo, /.///foo) | 1113 | // we are here because the last path element exists and is of file type directory |
1109 | if (weird_pathname) | 1114 | // reopen it using the passed flags |
1110 | flags = O_PATH|O_DIRECTORY|O_CLOEXEC; | 1115 | close(fd); |
1111 | // open last path segment | 1116 | fd = openat(parentfd, current_tok, flags|O_NOFOLLOW); |
1112 | fd = openat(parentfd, p + 1, flags|O_NOFOLLOW); | 1117 | close(parentfd); |
1113 | close(parentfd); | ||
1114 | } | ||
1115 | free(dup); | 1118 | free(dup); |
1116 | return fd; // -1 if open failed | 1119 | return fd; // -1 if open failed |
1117 | 1120 | ||