aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Simo Piiroinen <simo.piiroinen@jolla.com>2024-04-17 17:02:31 -0300
committerLibravatar Kelvin M. Klann <kmk3.code@protonmail.com>2024-04-25 09:16:41 -0300
commit53bc6589745a9f09bbc42a12dd14f9e81b6fc93f (patch)
tree27c6e6da0ab0d5bd51c0dc17dd211e112bcae83b /src
parentrefactor: make rundir lock variables global (diff)
downloadfirejail-53bc6589745a9f09bbc42a12dd14f9e81b6fc93f.tar.gz
firejail-53bc6589745a9f09bbc42a12dd14f9e81b6fc93f.tar.zst
firejail-53bc6589745a9f09bbc42a12dd14f9e81b6fc93f.zip
modif: improve flock handling
Changes: * Centralize flock handling in preproc.c * Add debug and error logging * Abort if anything fails Co-authored-by: Kelvin M. Klann <kmk3.code@protonmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/firejail/firejail.h4
-rw-r--r--src/firejail/main.c34
-rw-r--r--src/firejail/preproc.c83
3 files changed, 93 insertions, 28 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index e48591903..273cebd45 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -431,6 +431,10 @@ int net_get_mac(const char *ifname, unsigned char mac[6]);
431void net_config_interface(const char *dev, uint32_t ip, uint32_t mask, int mtu); 431void net_config_interface(const char *dev, uint32_t ip, uint32_t mask, int mtu);
432 432
433// preproc.c 433// preproc.c
434void preproc_lock_firejail_dir(void);
435void preproc_unlock_firejail_dir(void);
436void preproc_lock_firejail_network_dir(void);
437void preproc_unlock_firejail_network_dir(void);
434void preproc_build_firejail_dir(void); 438void preproc_build_firejail_dir(void);
435void preproc_mount_mnt_dir(void); 439void preproc_mount_mnt_dir(void);
436void preproc_clean_run(void); 440void preproc_clean_run(void);
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 34d5b091f..f00b46640 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -1169,15 +1169,9 @@ int main(int argc, char **argv, char **envp) {
1169 preproc_build_firejail_dir(); 1169 preproc_build_firejail_dir();
1170 const char *container_name = env_get("container"); 1170 const char *container_name = env_get("container");
1171 if (!container_name || strcmp(container_name, "firejail")) { 1171 if (!container_name || strcmp(container_name, "firejail")) {
1172 lockfd_directory = open(RUN_DIRECTORY_LOCK_FILE, O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR); 1172 preproc_lock_firejail_dir();
1173 if (lockfd_directory != -1) {
1174 int rv = fchown(lockfd_directory, 0, 0);
1175 (void) rv;
1176 flock(lockfd_directory, LOCK_EX);
1177 }
1178 preproc_clean_run(); 1173 preproc_clean_run();
1179 flock(lockfd_directory, LOCK_UN); 1174 preproc_unlock_firejail_dir();
1180 close(lockfd_directory);
1181 } 1175 }
1182 1176
1183 delete_run_files(getpid()); 1177 delete_run_files(getpid());
@@ -2990,12 +2984,7 @@ int main(int argc, char **argv, char **envp) {
2990 // check and assign an IP address - for macvlan it will be done again in the sandbox! 2984 // check and assign an IP address - for macvlan it will be done again in the sandbox!
2991 if (any_bridge_configured()) { 2985 if (any_bridge_configured()) {
2992 EUID_ROOT(); 2986 EUID_ROOT();
2993 lockfd_network = open(RUN_NETWORK_LOCK_FILE, O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR); 2987 preproc_lock_firejail_network_dir();
2994 if (lockfd_network != -1) {
2995 int rv = fchown(lockfd_network, 0, 0);
2996 (void) rv;
2997 flock(lockfd_network, LOCK_EX);
2998 }
2999 2988
3000 if (cfg.bridge0.configured && cfg.bridge0.arg_ip_none == 0) 2989 if (cfg.bridge0.configured && cfg.bridge0.arg_ip_none == 0)
3001 check_network(&cfg.bridge0); 2990 check_network(&cfg.bridge0);
@@ -3024,21 +3013,13 @@ int main(int argc, char **argv, char **envp) {
3024 3013
3025 // set name and x11 run files 3014 // set name and x11 run files
3026 EUID_ROOT(); 3015 EUID_ROOT();
3027 lockfd_directory = open(RUN_DIRECTORY_LOCK_FILE, O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR); 3016 preproc_lock_firejail_dir();
3028 if (lockfd_directory != -1) {
3029 int rv = fchown(lockfd_directory, 0, 0);
3030 (void) rv;
3031 flock(lockfd_directory, LOCK_EX);
3032 }
3033 if (cfg.name) 3017 if (cfg.name)
3034 set_name_run_file(sandbox_pid); 3018 set_name_run_file(sandbox_pid);
3035 int display = x11_display(); 3019 int display = x11_display();
3036 if (display > 0) 3020 if (display > 0)
3037 set_x11_run_file(sandbox_pid, display); 3021 set_x11_run_file(sandbox_pid, display);
3038 if (lockfd_directory != -1) { 3022 preproc_unlock_firejail_dir();
3039 flock(lockfd_directory, LOCK_UN);
3040 close(lockfd_directory);
3041 }
3042 EUID_USER(); 3023 EUID_USER();
3043 3024
3044#ifdef HAVE_DBUSPROXY 3025#ifdef HAVE_DBUSPROXY
@@ -3276,10 +3257,7 @@ int main(int argc, char **argv, char **envp) {
3276 close(parent_to_child_fds[1]); 3257 close(parent_to_child_fds[1]);
3277 3258
3278 EUID_ROOT(); 3259 EUID_ROOT();
3279 if (lockfd_network != -1) { 3260 preproc_unlock_firejail_network_dir();
3280 flock(lockfd_network, LOCK_UN);
3281 close(lockfd_network);
3282 }
3283 EUID_USER(); 3261 EUID_USER();
3284 3262
3285 // lock netfilter firewall 3263 // lock netfilter firewall
diff --git a/src/firejail/preproc.c b/src/firejail/preproc.c
index 2c7d4264d..335c4b0ba 100644
--- a/src/firejail/preproc.c
+++ b/src/firejail/preproc.c
@@ -18,13 +18,96 @@
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/ 19*/
20#include "firejail.h" 20#include "firejail.h"
21#include <sys/file.h>
21#include <sys/mount.h> 22#include <sys/mount.h>
22#include <sys/stat.h> 23#include <sys/stat.h>
23#include <sys/types.h> 24#include <sys/types.h>
24#include <dirent.h> 25#include <dirent.h>
26#include <fcntl.h>
25 27
26static int tmpfs_mounted = 0; 28static int tmpfs_mounted = 0;
27 29
30static void preproc_lock_file(const char *path, int *lockfd_ptr) {
31 assert(path != NULL);
32 assert(lockfd_ptr != NULL);
33
34 long pid = (long)getpid();
35 if (arg_debug)
36 fprintf(stderr, "pid=%ld: locking %s ...\n", pid, path);
37
38 if (*lockfd_ptr != -1) {
39 if (arg_debug)
40 fprintf(stderr, "pid=%ld: already locked %s\n", pid, path);
41 return;
42 }
43
44 int lockfd = open(path, O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR);
45 if (lockfd == -1) {
46 fprintf(stderr, "Error: cannot create a lockfile at %s\n", path);
47 errExit("open");
48 }
49
50 if (fchown(lockfd, 0, 0) == -1) {
51 fprintf(stderr, "Error: cannot chown root:root %s\n", path);
52 errExit("fchown");
53 }
54
55 if (flock(lockfd, LOCK_EX) == -1) {
56 fprintf(stderr, "Error: cannot lock %s\n", path);
57 errExit("flock");
58 }
59
60 *lockfd_ptr = lockfd;
61 if (arg_debug)
62 fprintf(stderr, "pid=%ld: locked %s\n", pid, path);
63}
64
65static void preproc_unlock_file(const char *path, int *lockfd_ptr) {
66 assert(path != NULL);
67 assert(lockfd_ptr != NULL);
68
69 long pid = (long)getpid();
70 if (arg_debug)
71 fprintf(stderr, "pid=%ld: unlocking %s ...\n", pid, path);
72
73 int lockfd = *lockfd_ptr;
74 if (lockfd == -1) {
75 if (arg_debug)
76 fprintf(stderr, "pid=%ld: already unlocked %s\n", pid, path);
77 return;
78 }
79
80 if (flock(lockfd, LOCK_UN) == -1) {
81 fprintf(stderr, "Error: cannot unlock %s\n", path);
82 errExit("flock");
83 }
84
85 if (close(lockfd) == -1) {
86 fprintf(stderr, "Error: cannot close %s\n", path);
87 errExit("close");
88 }
89
90 *lockfd_ptr = -1;
91 if (arg_debug)
92 fprintf(stderr, "pid=%ld: unlocked %s\n", pid, path);
93}
94
95void preproc_lock_firejail_dir(void) {
96 preproc_lock_file(RUN_DIRECTORY_LOCK_FILE, &lockfd_directory);
97}
98
99void preproc_unlock_firejail_dir(void) {
100 preproc_unlock_file(RUN_DIRECTORY_LOCK_FILE, &lockfd_directory);
101}
102
103void preproc_lock_firejail_network_dir(void) {
104 preproc_lock_file(RUN_NETWORK_LOCK_FILE, &lockfd_network);
105}
106
107void preproc_unlock_firejail_network_dir(void) {
108 preproc_unlock_file(RUN_NETWORK_LOCK_FILE, &lockfd_network);
109}
110
28// build /run/firejail directory 111// build /run/firejail directory
29void preproc_build_firejail_dir(void) { 112void preproc_build_firejail_dir(void) {
30 struct stat s; 113 struct stat s;