aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2021-05-16 15:48:14 +0200
committerLibravatar smitsohu <smitsohu@gmail.com>2021-05-16 15:48:14 +0200
commit825ac9cdc38c4285584e69d6f29102b149914dfe (patch)
treefd65f17f166a535f9a619c044022a3b933cc5f0c /src
parentUpdate disable-common.inc (diff)
downloadfirejail-825ac9cdc38c4285584e69d6f29102b149914dfe.tar.gz
firejail-825ac9cdc38c4285584e69d6f29102b149914dfe.tar.zst
firejail-825ac9cdc38c4285584e69d6f29102b149914dfe.zip
open files O_CLOEXEC|O_EXCL
Dumb patch that adds O_CLOEXEC to all open/fopen calls, even where it is obviously pointless. While at it, also add O_EXCL where it might be considered useful, for example to clear Coverity warnings, or on files that subsequently are used to configure a join sandbox. Pure defense in depth, this patch should have no observable effects.
Diffstat (limited to 'src')
-rw-r--r--src/firejail/appimage.c6
-rw-r--r--src/firejail/bandwidth.c32
-rw-r--r--src/firejail/caps.c2
-rw-r--r--src/firejail/cgroup.c20
-rw-r--r--src/firejail/checkcfg.c2
-rw-r--r--src/firejail/cpu.c6
-rw-r--r--src/firejail/dhcp.c2
-rw-r--r--src/firejail/env.c7
-rw-r--r--src/firejail/fs_dev.c6
-rw-r--r--src/firejail/fs_etc.c2
-rw-r--r--src/firejail/fs_home.c4
-rw-r--r--src/firejail/fs_hostname.c6
-rw-r--r--src/firejail/fs_lib.c2
-rw-r--r--src/firejail/fs_logger.c25
-rw-r--r--src/firejail/fs_trace.c9
-rw-r--r--src/firejail/fs_var.c9
-rw-r--r--src/firejail/join.c6
-rw-r--r--src/firejail/ls.c2
-rw-r--r--src/firejail/macros.c2
-rw-r--r--src/firejail/main.c16
-rw-r--r--src/firejail/network.c2
-rw-r--r--src/firejail/network_main.c2
-rw-r--r--src/firejail/no_sandbox.c14
-rw-r--r--src/firejail/preproc.c2
-rw-r--r--src/firejail/profile.c2
-rw-r--r--src/firejail/protocol.c4
-rw-r--r--src/firejail/pulseaudio.c2
-rw-r--r--src/firejail/restrict_users.c8
-rw-r--r--src/firejail/restricted_shell.c4
-rw-r--r--src/firejail/run_files.c6
-rw-r--r--src/firejail/sandbox.c4
-rw-r--r--src/firejail/seccomp.c8
-rw-r--r--src/firejail/shutdown.c2
-rw-r--r--src/firejail/util.c25
-rw-r--r--src/firejail/x11.c4
35 files changed, 111 insertions, 144 deletions
diff --git a/src/firejail/appimage.c b/src/firejail/appimage.c
index 59758bf2d..6b9fed765 100644
--- a/src/firejail/appimage.c
+++ b/src/firejail/appimage.c
@@ -67,7 +67,7 @@ void appimage_set(const char *appimage) {
67 67
68 // find or allocate a free loop device to use 68 // find or allocate a free loop device to use
69 EUID_ROOT(); 69 EUID_ROOT();
70 int cfd = open("/dev/loop-control", O_RDWR); 70 int cfd = open("/dev/loop-control", O_RDWR|O_CLOEXEC);
71 if (cfd == -1) 71 if (cfd == -1)
72 err_loop(); 72 err_loop();
73 int devnr = ioctl(cfd, LOOP_CTL_GET_FREE); 73 int devnr = ioctl(cfd, LOOP_CTL_GET_FREE);
@@ -78,7 +78,7 @@ void appimage_set(const char *appimage) {
78 errExit("asprintf"); 78 errExit("asprintf");
79 79
80 // associate loop device with appimage 80 // associate loop device with appimage
81 int lfd = open(devloop, O_RDONLY); 81 int lfd = open(devloop, O_RDONLY|O_CLOEXEC);
82 if (lfd == -1) 82 if (lfd == -1)
83 err_loop(); 83 err_loop();
84 if (ioctl(lfd, LOOP_SET_FD, ffd) == -1) 84 if (ioctl(lfd, LOOP_SET_FD, ffd) == -1)
@@ -146,7 +146,7 @@ void appimage_mount(void) {
146void appimage_clear(void) { 146void appimage_clear(void) {
147 EUID_ROOT(); 147 EUID_ROOT();
148 if (devloop) { 148 if (devloop) {
149 int lfd = open(devloop, O_RDONLY); 149 int lfd = open(devloop, O_RDONLY|O_CLOEXEC);
150 if (lfd != -1) { 150 if (lfd != -1) {
151 if (ioctl(lfd, LOOP_CLR_FD, 0) != -1) 151 if (ioctl(lfd, LOOP_CLR_FD, 0) != -1)
152 fmessage("AppImage detached\n"); 152 fmessage("AppImage detached\n");
diff --git a/src/firejail/bandwidth.c b/src/firejail/bandwidth.c
index 1c952c0bc..a085f2c27 100644
--- a/src/firejail/bandwidth.c
+++ b/src/firejail/bandwidth.c
@@ -22,6 +22,7 @@
22#include <sys/types.h> 22#include <sys/types.h>
23#include <sys/stat.h> 23#include <sys/stat.h>
24#include <unistd.h> 24#include <unistd.h>
25#include <errno.h>
25#include <net/if.h> 26#include <net/if.h>
26#include "firejail.h" 27#include "firejail.h"
27 28
@@ -119,26 +120,19 @@ static void bandwidth_create_run_file(pid_t pid) {
119 if (asprintf(&fname, "%s/%d-bandwidth", RUN_FIREJAIL_BANDWIDTH_DIR, (int) pid) == -1) 120 if (asprintf(&fname, "%s/%d-bandwidth", RUN_FIREJAIL_BANDWIDTH_DIR, (int) pid) == -1)
120 errExit("asprintf"); 121 errExit("asprintf");
121 122
122 // if the file already exists, do nothing
123 struct stat s;
124 if (stat(fname, &s) == 0) {
125 free(fname);
126 return;
127 }
128
129 // create an empty file and set mod and ownership 123 // create an empty file and set mod and ownership
130 /* coverity[toctou] */ 124 // if the file already exists, do nothing
131 FILE *fp = fopen(fname, "w"); 125 FILE *fp = fopen(fname, "wxe");
132 if (fp) { 126 free(fname);
133 SET_PERMS_STREAM(fp, 0, 0, 0644); 127 if (!fp) {
134 fclose(fp); 128 if (errno == EEXIST)
135 } 129 return;
136 else {
137 fprintf(stderr, "Error: cannot create bandwidth file\n"); 130 fprintf(stderr, "Error: cannot create bandwidth file\n");
138 exit(1); 131 exit(1);
139 } 132 }
140 133
141 free(fname); 134 SET_PERMS_STREAM(fp, 0, 0, 0644);
135 fclose(fp);
142} 136}
143 137
144 138
@@ -148,7 +142,7 @@ void network_set_run_file(pid_t pid) {
148 errExit("asprintf"); 142 errExit("asprintf");
149 143
150 // create an empty file and set mod and ownership 144 // create an empty file and set mod and ownership
151 FILE *fp = fopen(fname, "w"); 145 FILE *fp = fopen(fname, "we");
152 if (fp) { 146 if (fp) {
153 if (cfg.bridge0.configured) 147 if (cfg.bridge0.configured)
154 fprintf(fp, "%s:%s\n", cfg.bridge0.dev, cfg.bridge0.devsandbox); 148 fprintf(fp, "%s:%s\n", cfg.bridge0.dev, cfg.bridge0.devsandbox);
@@ -178,7 +172,7 @@ static void read_bandwidth_file(pid_t pid) {
178 if (asprintf(&fname, "%s/%d-bandwidth", RUN_FIREJAIL_BANDWIDTH_DIR, (int) pid) == -1) 172 if (asprintf(&fname, "%s/%d-bandwidth", RUN_FIREJAIL_BANDWIDTH_DIR, (int) pid) == -1)
179 errExit("asprintf"); 173 errExit("asprintf");
180 174
181 FILE *fp = fopen(fname, "r"); 175 FILE *fp = fopen(fname, "re");
182 if (fp) { 176 if (fp) {
183 char buf[1024]; 177 char buf[1024];
184 while (fgets(buf, 1024,fp)) { 178 while (fgets(buf, 1024,fp)) {
@@ -214,7 +208,7 @@ static void write_bandwidth_file(pid_t pid) {
214 if (asprintf(&fname, "%s/%d-bandwidth", RUN_FIREJAIL_BANDWIDTH_DIR, (int) pid) == -1) 208 if (asprintf(&fname, "%s/%d-bandwidth", RUN_FIREJAIL_BANDWIDTH_DIR, (int) pid) == -1)
215 errExit("asprintf"); 209 errExit("asprintf");
216 210
217 FILE *fp = fopen(fname, "w"); 211 FILE *fp = fopen(fname, "we");
218 if (fp) { 212 if (fp) {
219 IFBW *ptr = ifbw; 213 IFBW *ptr = ifbw;
220 while (ptr) { 214 while (ptr) {
@@ -307,7 +301,7 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in
307 char *fname; 301 char *fname;
308 if (asprintf(&fname, "%s/%d-netmap", RUN_FIREJAIL_NETWORK_DIR, (int) pid) == -1) 302 if (asprintf(&fname, "%s/%d-netmap", RUN_FIREJAIL_NETWORK_DIR, (int) pid) == -1)
309 errExit("asprintf"); 303 errExit("asprintf");
310 FILE *fp = fopen(fname, "r"); 304 FILE *fp = fopen(fname, "re");
311 if (!fp) { 305 if (!fp) {
312 fprintf(stderr, "Error: cannot read network map file %s\n", fname); 306 fprintf(stderr, "Error: cannot read network map file %s\n", fname);
313 exit(1); 307 exit(1);
diff --git a/src/firejail/caps.c b/src/firejail/caps.c
index 597f9915b..5e02b99c2 100644
--- a/src/firejail/caps.c
+++ b/src/firejail/caps.c
@@ -389,7 +389,7 @@ static uint64_t extract_caps(int pid) {
389 errExit("asprintf"); 389 errExit("asprintf");
390 390
391 EUID_ROOT(); // grsecurity 391 EUID_ROOT(); // grsecurity
392 FILE *fp = fopen(file, "r"); 392 FILE *fp = fopen(file, "re");
393 EUID_USER(); // grsecurity 393 EUID_USER(); // grsecurity
394 if (!fp) 394 if (!fp)
395 goto errexit; 395 goto errexit;
diff --git a/src/firejail/cgroup.c b/src/firejail/cgroup.c
index 986b1157d..e7ffbca36 100644
--- a/src/firejail/cgroup.c
+++ b/src/firejail/cgroup.c
@@ -26,7 +26,7 @@ void save_cgroup(void) {
26 if (cfg.cgroup == NULL) 26 if (cfg.cgroup == NULL)
27 return; 27 return;
28 28
29 FILE *fp = fopen(RUN_CGROUP_CFG, "w"); 29 FILE *fp = fopen(RUN_CGROUP_CFG, "wxe");
30 if (fp) { 30 if (fp) {
31 fprintf(fp, "%s", cfg.cgroup); 31 fprintf(fp, "%s", cfg.cgroup);
32 fflush(0); 32 fflush(0);
@@ -48,7 +48,7 @@ void load_cgroup(const char *fname) {
48 if (!fname) 48 if (!fname)
49 return; 49 return;
50 50
51 FILE *fp = fopen(fname, "r"); 51 FILE *fp = fopen(fname, "re");
52 if (fp) { 52 if (fp) {
53 char buf[MAXBUF]; 53 char buf[MAXBUF];
54 if (fgets(buf, MAXBUF, fp)) { 54 if (fgets(buf, MAXBUF, fp)) {
@@ -91,19 +91,19 @@ void set_cgroup(const char *path) {
91 goto errout; 91 goto errout;
92 92
93 // tasks file exists 93 // tasks file exists
94 struct stat s; 94 FILE *fp = fopen(path, "ae");
95 if (stat(path, &s) == -1) 95 if (!fp)
96 goto errout; 96 goto errout;
97
98 // task file belongs to the user running the sandbox 97 // task file belongs to the user running the sandbox
98 int fd = fileno(fp);
99 if (fd == -1)
100 errExit("fileno");
101 struct stat s;
102 if (fstat(fd, &s) == -1)
103 errExit("fstat");
99 if (s.st_uid != getuid() && s.st_gid != getgid()) 104 if (s.st_uid != getuid() && s.st_gid != getgid())
100 goto errout2; 105 goto errout2;
101
102 // add the task to cgroup 106 // add the task to cgroup
103 /* coverity[toctou] */
104 FILE *fp = fopen(path, "a");
105 if (!fp)
106 goto errout;
107 pid_t pid = getpid(); 107 pid_t pid = getpid();
108 int rv = fprintf(fp, "%d\n", pid); 108 int rv = fprintf(fp, "%d\n", pid);
109 (void) rv; 109 (void) rv;
diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c
index e1613b325..d6643cf3a 100644
--- a/src/firejail/checkcfg.c
+++ b/src/firejail/checkcfg.c
@@ -59,7 +59,7 @@ int checkcfg(int val) {
59 59
60 // open configuration file 60 // open configuration file
61 const char *fname = SYSCONFDIR "/firejail.config"; 61 const char *fname = SYSCONFDIR "/firejail.config";
62 fp = fopen(fname, "r"); 62 fp = fopen(fname, "re");
63 if (!fp) { 63 if (!fp) {
64#ifdef HAVE_GLOBALCFG 64#ifdef HAVE_GLOBALCFG
65 fprintf(stderr, "Error: Firejail configuration file %s not found\n", fname); 65 fprintf(stderr, "Error: Firejail configuration file %s not found\n", fname);
diff --git a/src/firejail/cpu.c b/src/firejail/cpu.c
index 3427e8ade..fe7258fb0 100644
--- a/src/firejail/cpu.c
+++ b/src/firejail/cpu.c
@@ -75,7 +75,7 @@ void save_cpu(void) {
75 if (cfg.cpus == 0) 75 if (cfg.cpus == 0)
76 return; 76 return;
77 77
78 FILE *fp = fopen(RUN_CPU_CFG, "w"); 78 FILE *fp = fopen(RUN_CPU_CFG, "wxe");
79 if (fp) { 79 if (fp) {
80 fprintf(fp, "%x\n", cfg.cpus); 80 fprintf(fp, "%x\n", cfg.cpus);
81 SET_PERMS_STREAM(fp, 0, 0, 0600); 81 SET_PERMS_STREAM(fp, 0, 0, 0600);
@@ -91,7 +91,7 @@ void load_cpu(const char *fname) {
91 if (!fname) 91 if (!fname)
92 return; 92 return;
93 93
94 FILE *fp = fopen(fname, "r"); 94 FILE *fp = fopen(fname, "re");
95 if (fp) { 95 if (fp) {
96 unsigned tmp; 96 unsigned tmp;
97 int rv = fscanf(fp, "%x", &tmp); 97 int rv = fscanf(fp, "%x", &tmp);
@@ -139,7 +139,7 @@ static void print_cpu(int pid) {
139 } 139 }
140 140
141 EUID_ROOT(); // grsecurity 141 EUID_ROOT(); // grsecurity
142 FILE *fp = fopen(file, "r"); 142 FILE *fp = fopen(file, "re");
143 EUID_USER(); // grsecurity 143 EUID_USER(); // grsecurity
144 if (!fp) { 144 if (!fp) {
145 printf(" Error: cannot open %s\n", file); 145 printf(" Error: cannot open %s\n", file);
diff --git a/src/firejail/dhcp.c b/src/firejail/dhcp.c
index bdbb338d5..5bcdcad37 100644
--- a/src/firejail/dhcp.c
+++ b/src/firejail/dhcp.c
@@ -93,7 +93,7 @@ static pid_t dhcp_read_pidfile(const Dhclient *client) {
93 while (found == 0 && tries < 10) { 93 while (found == 0 && tries < 10) {
94 if (tries >= 1) 94 if (tries >= 1)
95 usleep(100000); 95 usleep(100000);
96 FILE *pidfile = fopen(client->pid_file, "r"); 96 FILE *pidfile = fopen(client->pid_file, "re");
97 if (pidfile) { 97 if (pidfile) {
98 long pid; 98 long pid;
99 if (fscanf(pidfile, "%ld", &pid) == 1) 99 if (fscanf(pidfile, "%ld", &pid) == 1)
diff --git a/src/firejail/env.c b/src/firejail/env.c
index 03818df0b..f5e9dd980 100644
--- a/src/firejail/env.c
+++ b/src/firejail/env.c
@@ -59,12 +59,7 @@ void env_ibus_load(void) {
59 if (asprintf(&dirname, "%s/.config/ibus/bus", cfg.homedir) == -1) 59 if (asprintf(&dirname, "%s/.config/ibus/bus", cfg.homedir) == -1)
60 errExit("asprintf"); 60 errExit("asprintf");
61 61
62 struct stat s;
63 if (stat(dirname, &s) == -1)
64 return;
65
66 // find the file 62 // find the file
67 /* coverity[toctou] */
68 DIR *dir = opendir(dirname); 63 DIR *dir = opendir(dirname);
69 if (!dir) { 64 if (!dir) {
70 free(dirname); 65 free(dirname);
@@ -84,7 +79,7 @@ void env_ibus_load(void) {
84 char *fname; 79 char *fname;
85 if (asprintf(&fname, "%s/%s", dirname, entry->d_name) == -1) 80 if (asprintf(&fname, "%s/%s", dirname, entry->d_name) == -1)
86 errExit("asprintf"); 81 errExit("asprintf");
87 FILE *fp = fopen(fname, "r"); 82 FILE *fp = fopen(fname, "re");
88 free(fname); 83 free(fname);
89 if (!fp) 84 if (!fp)
90 continue; 85 continue;
diff --git a/src/firejail/fs_dev.c b/src/firejail/fs_dev.c
index 2f0067c93..8c2870a4d 100644
--- a/src/firejail/fs_dev.c
+++ b/src/firejail/fs_dev.c
@@ -122,7 +122,7 @@ static void deventry_mount(void) {
122 i++; 122 i++;
123 continue; 123 continue;
124 } 124 }
125 FILE *fp = fopen(dev[i].dev_fname, "w"); 125 FILE *fp = fopen(dev[i].dev_fname, "we");
126 if (fp) { 126 if (fp) {
127 fprintf(fp, "\n"); 127 fprintf(fp, "\n");
128 SET_PERMS_STREAM(fp, s.st_uid, s.st_gid, s.st_mode); 128 SET_PERMS_STREAM(fp, s.st_uid, s.st_gid, s.st_mode);
@@ -218,7 +218,7 @@ void fs_private_dev(void){
218 struct stat s; 218 struct stat s;
219 if (stat("/dev/log", &s) == 0) { 219 if (stat("/dev/log", &s) == 0) {
220 have_devlog = 1; 220 have_devlog = 1;
221 FILE *fp = fopen(RUN_DEVLOG_FILE, "w"); 221 FILE *fp = fopen(RUN_DEVLOG_FILE, "we");
222 if (!fp) 222 if (!fp)
223 have_devlog = 0; 223 have_devlog = 0;
224 else { 224 else {
@@ -239,7 +239,7 @@ void fs_private_dev(void){
239 239
240 // bring back /dev/log 240 // bring back /dev/log
241 if (have_devlog) { 241 if (have_devlog) {
242 FILE *fp = fopen("/dev/log", "w"); 242 FILE *fp = fopen("/dev/log", "we");
243 if (fp) { 243 if (fp) {
244 fprintf(fp, "\n"); 244 fprintf(fp, "\n");
245 fclose(fp); 245 fclose(fp);
diff --git a/src/firejail/fs_etc.c b/src/firejail/fs_etc.c
index 8cb25a1ff..b0e1e1bf1 100644
--- a/src/firejail/fs_etc.c
+++ b/src/firejail/fs_etc.c
@@ -52,7 +52,7 @@ void fs_machineid(void) {
52 mid.u8[8] = (mid.u8[8] & 0x3F) | 0x80; 52 mid.u8[8] = (mid.u8[8] & 0x3F) | 0x80;
53 53
54 // write it in a file 54 // write it in a file
55 FILE *fp = fopen(RUN_MACHINEID, "w"); 55 FILE *fp = fopen(RUN_MACHINEID, "we");
56 if (!fp) 56 if (!fp)
57 errExit("fopen"); 57 errExit("fopen");
58 fprintf(fp, "%08x%08x%08x%08x\n", mid.u32[0], mid.u32[1], mid.u32[2], mid.u32[3]); 58 fprintf(fp, "%08x%08x%08x%08x\n", mid.u32[0], mid.u32[1], mid.u32[2], mid.u32[3]);
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index 46f32d7ad..c7b87235a 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -130,7 +130,7 @@ static int store_xauthority(void) {
130 } 130 }
131 131
132 // create an empty file as root, and change ownership to user 132 // create an empty file as root, and change ownership to user
133 FILE *fp = fopen(dest, "w"); 133 FILE *fp = fopen(dest, "we");
134 if (fp) { 134 if (fp) {
135 fprintf(fp, "\n"); 135 fprintf(fp, "\n");
136 SET_PERMS_STREAM(fp, getuid(), getgid(), 0600); 136 SET_PERMS_STREAM(fp, getuid(), getgid(), 0600);
@@ -178,7 +178,7 @@ static int store_asoundrc(void) {
178 } 178 }
179 179
180 // create an empty file as root, and change ownership to user 180 // create an empty file as root, and change ownership to user
181 FILE *fp = fopen(dest, "w"); 181 FILE *fp = fopen(dest, "we");
182 if (fp) { 182 if (fp) {
183 fprintf(fp, "\n"); 183 fprintf(fp, "\n");
184 SET_PERMS_STREAM(fp, getuid(), getgid(), 0644); 184 SET_PERMS_STREAM(fp, getuid(), getgid(), 0644);
diff --git a/src/firejail/fs_hostname.c b/src/firejail/fs_hostname.c
index 8a3bb71ea..80046f7ae 100644
--- a/src/firejail/fs_hostname.c
+++ b/src/firejail/fs_hostname.c
@@ -47,11 +47,11 @@ void fs_hostname(const char *hostname) {
47 printf("Creating a new /etc/hosts file\n"); 47 printf("Creating a new /etc/hosts file\n");
48 // copy /etc/host into our new file, and modify it on the fly 48 // copy /etc/host into our new file, and modify it on the fly
49 /* coverity[toctou] */ 49 /* coverity[toctou] */
50 FILE *fp1 = fopen("/etc/hosts", "r"); 50 FILE *fp1 = fopen("/etc/hosts", "re");
51 if (!fp1) 51 if (!fp1)
52 goto errexit; 52 goto errexit;
53 53
54 FILE *fp2 = fopen(RUN_HOSTS_FILE, "w"); 54 FILE *fp2 = fopen(RUN_HOSTS_FILE, "we");
55 if (!fp2) { 55 if (!fp2) {
56 fclose(fp1); 56 fclose(fp1);
57 goto errexit; 57 goto errexit;
@@ -165,7 +165,7 @@ void fs_resolvconf(void) {
165 165
166 if (arg_debug) 166 if (arg_debug)
167 printf("Creating a new /etc/resolv.conf file\n"); 167 printf("Creating a new /etc/resolv.conf file\n");
168 FILE *fp = fopen("/etc/resolv.conf", "w"); 168 FILE *fp = fopen("/etc/resolv.conf", "wxe");
169 if (!fp) { 169 if (!fp) {
170 fprintf(stderr, "Error: cannot create /etc/resolv.conf file\n"); 170 fprintf(stderr, "Error: cannot create /etc/resolv.conf file\n");
171 exit(1); 171 exit(1);
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c
index 85fb70854..5df356d04 100644
--- a/src/firejail/fs_lib.c
+++ b/src/firejail/fs_lib.c
@@ -221,7 +221,7 @@ void fslib_mount_libs(const char *full_path, unsigned user) {
221 sbox_run(mask | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, full_path, RUN_LIB_FILE); 221 sbox_run(mask | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, full_path, RUN_LIB_FILE);
222 222
223 // open the list of libraries and install them on by one 223 // open the list of libraries and install them on by one
224 FILE *fp = fopen(RUN_LIB_FILE, "r"); 224 FILE *fp = fopen(RUN_LIB_FILE, "re");
225 if (!fp) 225 if (!fp)
226 errExit("fopen"); 226 errExit("fopen");
227 227
diff --git a/src/firejail/fs_logger.c b/src/firejail/fs_logger.c
index 67ad4b52e..604e297b1 100644
--- a/src/firejail/fs_logger.c
+++ b/src/firejail/fs_logger.c
@@ -92,7 +92,7 @@ void fs_logger_print(void) {
92 if (!head) 92 if (!head)
93 return; 93 return;
94 94
95 FILE *fp = fopen(RUN_FSLOGGER_FILE, "a"); 95 FILE *fp = fopen(RUN_FSLOGGER_FILE, "ae");
96 if (!fp) { 96 if (!fp) {
97 perror("fopen"); 97 perror("fopen");
98 return; 98 return;
@@ -123,15 +123,8 @@ void fs_logger_print_log(pid_t pid) {
123 // in case the pid is that of a firejail process, use the pid of the first child process 123 // in case the pid is that of a firejail process, use the pid of the first child process
124 pid = switch_to_child(pid); 124 pid = switch_to_child(pid);
125 125
126 // check privileges for non-root users 126 // exit if no permission to join the sandbox
127 uid_t uid = getuid(); 127 check_join_permission(pid);
128 if (uid != 0) {
129 uid_t sandbox_uid = pid_get_uid(pid);
130 if (uid != sandbox_uid) {
131 fprintf(stderr, "Error: permission denied\n");
132 exit(1);
133 }
134 }
135 128
136 // print RUN_FSLOGGER_FILE 129 // print RUN_FSLOGGER_FILE
137 char *fname; 130 char *fname;
@@ -139,24 +132,16 @@ void fs_logger_print_log(pid_t pid) {
139 errExit("asprintf"); 132 errExit("asprintf");
140 133
141 EUID_ROOT(); 134 EUID_ROOT();
142 struct stat s; 135 FILE *fp = fopen(fname, "re");
143 if (stat(fname, &s) == -1 || s.st_uid != 0) { 136 free(fname);
144 fprintf(stderr, "Error: Cannot access filesystem log\n");
145 exit(1);
146 }
147
148 /* coverity[toctou] */
149 FILE *fp = fopen(fname, "r");
150 if (!fp) { 137 if (!fp) {
151 fprintf(stderr, "Error: Cannot open filesystem log\n"); 138 fprintf(stderr, "Error: Cannot open filesystem log\n");
152 exit(1); 139 exit(1);
153 } 140 }
154
155 char buf[MAXBUF]; 141 char buf[MAXBUF];
156 while (fgets(buf, MAXBUF, fp)) 142 while (fgets(buf, MAXBUF, fp))
157 printf("%s", buf); 143 printf("%s", buf);
158 fclose(fp); 144 fclose(fp);
159 free(fname);
160 145
161 exit(0); 146 exit(0);
162} 147}
diff --git a/src/firejail/fs_trace.c b/src/firejail/fs_trace.c
index 8f939b5f5..1fc38361e 100644
--- a/src/firejail/fs_trace.c
+++ b/src/firejail/fs_trace.c
@@ -33,8 +33,7 @@ void fs_trace_preload(void) {
33 if (stat("/etc/ld.so.preload", &s)) { 33 if (stat("/etc/ld.so.preload", &s)) {
34 if (arg_debug) 34 if (arg_debug)
35 printf("Creating an empty /etc/ld.so.preload file\n"); 35 printf("Creating an empty /etc/ld.so.preload file\n");
36 /* coverity[toctou] */ 36 FILE *fp = fopen("/etc/ld.so.preload", "wxe");
37 FILE *fp = fopen("/etc/ld.so.preload", "w");
38 if (!fp) 37 if (!fp)
39 errExit("fopen"); 38 errExit("fopen");
40 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH); 39 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
@@ -64,11 +63,11 @@ void fs_tracefile(void) {
64 if (ftruncate(fd, 0) == -1) 63 if (ftruncate(fd, 0) == -1)
65 errExit("ftruncate"); 64 errExit("ftruncate");
66 EUID_ROOT(); 65 EUID_ROOT();
67 FILE *fp = fopen(RUN_TRACE_FILE, "w"); 66 FILE *fp = fopen(RUN_TRACE_FILE, "we");
68 if (!fp) 67 if (!fp)
69 errExit("fopen " RUN_TRACE_FILE); 68 errExit("fopen " RUN_TRACE_FILE);
70 fclose(fp); 69 fclose(fp);
71 fs_logger2("touch ", arg_tracefile); 70 fs_logger2("touch", arg_tracefile);
72 // mount using the symbolic link in /proc/self/fd 71 // mount using the symbolic link in /proc/self/fd
73 if (arg_debug) 72 if (arg_debug)
74 printf("Bind mount %s to %s\n", arg_tracefile, RUN_TRACE_FILE); 73 printf("Bind mount %s to %s\n", arg_tracefile, RUN_TRACE_FILE);
@@ -88,7 +87,7 @@ void fs_trace(void) {
88 if (arg_debug) 87 if (arg_debug)
89 printf("Create the new ld.so.preload file\n"); 88 printf("Create the new ld.so.preload file\n");
90 89
91 FILE *fp = fopen(RUN_LDPRELOAD_FILE, "w"); 90 FILE *fp = fopen(RUN_LDPRELOAD_FILE, "we");
92 if (!fp) 91 if (!fp)
93 errExit("fopen"); 92 errExit("fopen");
94 const char *prefix = RUN_FIREJAIL_LIB_DIR; 93 const char *prefix = RUN_FIREJAIL_LIB_DIR;
diff --git a/src/firejail/fs_var.c b/src/firejail/fs_var.c
index f07581cd8..64238e070 100644
--- a/src/firejail/fs_var.c
+++ b/src/firejail/fs_var.c
@@ -127,7 +127,7 @@ void fs_var_log(void) {
127 127
128 // create an empty /var/log/wtmp file 128 // create an empty /var/log/wtmp file
129 /* coverity[toctou] */ 129 /* coverity[toctou] */
130 FILE *fp = fopen("/var/log/wtmp", "w"); 130 FILE *fp = fopen("/var/log/wtmp", "wxe");
131 if (fp) { 131 if (fp) {
132 SET_PERMS_STREAM(fp, 0, wtmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH); 132 SET_PERMS_STREAM(fp, 0, wtmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH);
133 fclose(fp); 133 fclose(fp);
@@ -135,7 +135,7 @@ void fs_var_log(void) {
135 fs_logger("touch /var/log/wtmp"); 135 fs_logger("touch /var/log/wtmp");
136 136
137 // create an empty /var/log/btmp file 137 // create an empty /var/log/btmp file
138 fp = fopen("/var/log/btmp", "w"); 138 fp = fopen("/var/log/btmp", "wxe");
139 if (fp) { 139 if (fp) {
140 SET_PERMS_STREAM(fp, 0, wtmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP); 140 SET_PERMS_STREAM(fp, 0, wtmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP);
141 fclose(fp); 141 fclose(fp);
@@ -158,8 +158,7 @@ void fs_var_lib(void) {
158 fs_logger("tmpfs /var/lib/dhcp"); 158 fs_logger("tmpfs /var/lib/dhcp");
159 159
160 // isc dhcp server requires a /var/lib/dhcp/dhcpd.leases file 160 // isc dhcp server requires a /var/lib/dhcp/dhcpd.leases file
161 FILE *fp = fopen("/var/lib/dhcp/dhcpd.leases", "w"); 161 FILE *fp = fopen("/var/lib/dhcp/dhcpd.leases", "wxe");
162
163 if (fp) { 162 if (fp) {
164 fprintf(fp, "\n"); 163 fprintf(fp, "\n");
165 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); 164 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
@@ -296,7 +295,7 @@ void fs_var_utmp(void) {
296 printf("Create the new utmp file\n"); 295 printf("Create the new utmp file\n");
297 296
298 /* coverity[toctou] */ 297 /* coverity[toctou] */
299 FILE *fp = fopen(RUN_UTMP_FILE, "w"); 298 FILE *fp = fopen(RUN_UTMP_FILE, "wxe");
300 if (!fp) 299 if (!fp)
301 errExit("fopen"); 300 errExit("fopen");
302 301
diff --git a/src/firejail/join.c b/src/firejail/join.c
index 1575a7469..bab4b830f 100644
--- a/src/firejail/join.c
+++ b/src/firejail/join.c
@@ -103,7 +103,7 @@ static void extract_x11_display(pid_t pid) {
103 if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_X11_DIR, pid) == -1) 103 if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_X11_DIR, pid) == -1)
104 errExit("asprintf"); 104 errExit("asprintf");
105 105
106 FILE *fp = fopen(fname, "r"); 106 FILE *fp = fopen(fname, "re");
107 free(fname); 107 free(fname);
108 if (!fp) 108 if (!fp)
109 return; 109 return;
@@ -219,7 +219,7 @@ static void extract_caps(pid_t pid) {
219 perror("asprintf"); 219 perror("asprintf");
220 exit(1); 220 exit(1);
221 } 221 }
222 FILE *fp = fopen(file, "r"); 222 FILE *fp = fopen(file, "re");
223 if (!fp) 223 if (!fp)
224 goto errexit; 224 goto errexit;
225 225
@@ -266,7 +266,7 @@ static void extract_user_namespace(pid_t pid) {
266 char *uidmap; 266 char *uidmap;
267 if (asprintf(&uidmap, "/proc/%u/uid_map", pid) == -1) 267 if (asprintf(&uidmap, "/proc/%u/uid_map", pid) == -1)
268 errExit("asprintf"); 268 errExit("asprintf");
269 FILE *fp = fopen(uidmap, "r"); 269 FILE *fp = fopen(uidmap, "re");
270 if (!fp) { 270 if (!fp) {
271 free(uidmap); 271 free(uidmap);
272 return; 272 return;
diff --git a/src/firejail/ls.c b/src/firejail/ls.c
index 63ef2309b..796c42290 100644
--- a/src/firejail/ls.c
+++ b/src/firejail/ls.c
@@ -221,7 +221,7 @@ void cat(const char *path) {
221 221
222 if (arg_debug) 222 if (arg_debug)
223 printf("cat %s\n", path); 223 printf("cat %s\n", path);
224 FILE *fp = fopen(path, "r"); 224 FILE *fp = fopen(path, "re");
225 if (!fp) { 225 if (!fp) {
226 fprintf(stderr, "Error: cannot read %s\n", path); 226 fprintf(stderr, "Error: cannot read %s\n", path);
227 exit(1); 227 exit(1);
diff --git a/src/firejail/macros.c b/src/firejail/macros.c
index 7f2f6dbf3..bcac1feb4 100644
--- a/src/firejail/macros.c
+++ b/src/firejail/macros.c
@@ -99,7 +99,7 @@ static char *resolve_xdg(const char *var) {
99 99
100 if (asprintf(&fname, "%s/.config/user-dirs.dirs", cfg.homedir) == -1) 100 if (asprintf(&fname, "%s/.config/user-dirs.dirs", cfg.homedir) == -1)
101 errExit("asprintf"); 101 errExit("asprintf");
102 FILE *fp = fopen(fname, "r"); 102 FILE *fp = fopen(fname, "re");
103 if (!fp) { 103 if (!fp) {
104 free(fname); 104 free(fname);
105 return NULL; 105 return NULL;
diff --git a/src/firejail/main.c b/src/firejail/main.c
index a0ee1e433..cf14c077a 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -535,7 +535,7 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
535 char *fname; 535 char *fname;
536 if (asprintf(&fname, RUN_FIREJAIL_PROFILE_DIR "/%d", pid) == -1) 536 if (asprintf(&fname, RUN_FIREJAIL_PROFILE_DIR "/%d", pid) == -1)
537 errExit("asprintf"); 537 errExit("asprintf");
538 FILE *fp = fopen(fname, "r"); 538 FILE *fp = fopen(fname, "re");
539 if (!fp) { 539 if (!fp) {
540 fprintf(stderr, "Error: sandbox %s not found\n", argv[i] + 16); 540 fprintf(stderr, "Error: sandbox %s not found\n", argv[i] + 16);
541 exit(1); 541 exit(1);
@@ -1043,7 +1043,7 @@ int main(int argc, char **argv, char **envp) {
1043 preproc_build_firejail_dir(); 1043 preproc_build_firejail_dir();
1044 const char *container_name = env_get("container"); 1044 const char *container_name = env_get("container");
1045 if (!container_name || strcmp(container_name, "firejail")) { 1045 if (!container_name || strcmp(container_name, "firejail")) {
1046 lockfd_directory = open(RUN_DIRECTORY_LOCK_FILE, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); 1046 lockfd_directory = open(RUN_DIRECTORY_LOCK_FILE, O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR);
1047 if (lockfd_directory != -1) { 1047 if (lockfd_directory != -1) {
1048 int rv = fchown(lockfd_directory, 0, 0); 1048 int rv = fchown(lockfd_directory, 0, 0);
1049 (void) rv; 1049 (void) rv;
@@ -1145,7 +1145,7 @@ int main(int argc, char **argv, char **envp) {
1145 1145
1146#ifdef DEBUG_RESTRICTED_SHELL 1146#ifdef DEBUG_RESTRICTED_SHELL
1147 {EUID_ROOT(); 1147 {EUID_ROOT();
1148 FILE *fp = fopen("/firelog", "w"); 1148 FILE *fp = fopen("/firelog", "we");
1149 if (fp) { 1149 if (fp) {
1150 int i; 1150 int i;
1151 fprintf(fp, "argc %d: ", argc); 1151 fprintf(fp, "argc %d: ", argc);
@@ -1164,7 +1164,7 @@ int main(int argc, char **argv, char **envp) {
1164 strncmp(argv[2], "scp ", 4) == 0) { 1164 strncmp(argv[2], "scp ", 4) == 0) {
1165#ifdef DEBUG_RESTRICTED_SHELL 1165#ifdef DEBUG_RESTRICTED_SHELL
1166 {EUID_ROOT(); 1166 {EUID_ROOT();
1167 FILE *fp = fopen("/firelog", "a"); 1167 FILE *fp = fopen("/firelog", "ae");
1168 if (fp) { 1168 if (fp) {
1169 fprintf(fp, "run without a sandbox\n"); 1169 fprintf(fp, "run without a sandbox\n");
1170 fclose(fp); 1170 fclose(fp);
@@ -1197,7 +1197,7 @@ int main(int argc, char **argv, char **envp) {
1197 1197
1198#ifdef DEBUG_RESTRICTED_SHELL 1198#ifdef DEBUG_RESTRICTED_SHELL
1199 {EUID_ROOT(); 1199 {EUID_ROOT();
1200 FILE *fp = fopen("/firelog", "a"); 1200 FILE *fp = fopen("/firelog", "ae");
1201 if (fp) { 1201 if (fp) {
1202 fprintf(fp, "fullargc %d: ", fullargc); 1202 fprintf(fp, "fullargc %d: ", fullargc);
1203 int i; 1203 int i;
@@ -1219,7 +1219,7 @@ int main(int argc, char **argv, char **envp) {
1219 1219
1220#ifdef DEBUG_RESTRICTED_SHELL 1220#ifdef DEBUG_RESTRICTED_SHELL
1221 {EUID_ROOT(); 1221 {EUID_ROOT();
1222 FILE *fp = fopen("/firelog", "a"); 1222 FILE *fp = fopen("/firelog", "ae");
1223 if (fp) { 1223 if (fp) {
1224 fprintf(fp, "argc %d: ", argc); 1224 fprintf(fp, "argc %d: ", argc);
1225 int i; 1225 int i;
@@ -2852,7 +2852,7 @@ int main(int argc, char **argv, char **envp) {
2852 // check and assign an IP address - for macvlan it will be done again in the sandbox! 2852 // check and assign an IP address - for macvlan it will be done again in the sandbox!
2853 if (any_bridge_configured()) { 2853 if (any_bridge_configured()) {
2854 EUID_ROOT(); 2854 EUID_ROOT();
2855 lockfd_network = open(RUN_NETWORK_LOCK_FILE, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); 2855 lockfd_network = open(RUN_NETWORK_LOCK_FILE, O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR);
2856 if (lockfd_network != -1) { 2856 if (lockfd_network != -1) {
2857 int rv = fchown(lockfd_network, 0, 0); 2857 int rv = fchown(lockfd_network, 0, 0);
2858 (void) rv; 2858 (void) rv;
@@ -2892,7 +2892,7 @@ int main(int argc, char **argv, char **envp) {
2892 2892
2893 // set name and x11 run files 2893 // set name and x11 run files
2894 EUID_ROOT(); 2894 EUID_ROOT();
2895 lockfd_directory = open(RUN_DIRECTORY_LOCK_FILE, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); 2895 lockfd_directory = open(RUN_DIRECTORY_LOCK_FILE, O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR);
2896 if (lockfd_directory != -1) { 2896 if (lockfd_directory != -1) {
2897 int rv = fchown(lockfd_directory, 0, 0); 2897 int rv = fchown(lockfd_directory, 0, 0);
2898 (void) rv; 2898 (void) rv;
diff --git a/src/firejail/network.c b/src/firejail/network.c
index f7142cefd..289e164c6 100644
--- a/src/firejail/network.c
+++ b/src/firejail/network.c
@@ -217,7 +217,7 @@ int net_add_route(uint32_t ip, uint32_t mask, uint32_t gw) {
217 217
218#define BUFSIZE 1024 218#define BUFSIZE 1024
219uint32_t network_get_defaultgw(void) { 219uint32_t network_get_defaultgw(void) {
220 FILE *fp = fopen("/proc/self/net/route", "r"); 220 FILE *fp = fopen("/proc/self/net/route", "re");
221 if (!fp) 221 if (!fp)
222 errExit("fopen"); 222 errExit("fopen");
223 223
diff --git a/src/firejail/network_main.c b/src/firejail/network_main.c
index ee3c00872..d3e75bbed 100644
--- a/src/firejail/network_main.c
+++ b/src/firejail/network_main.c
@@ -292,7 +292,7 @@ void net_dns_print(pid_t pid) {
292 errExit("chdir"); 292 errExit("chdir");
293 293
294 // access /etc/resolv.conf 294 // access /etc/resolv.conf
295 FILE *fp = fopen("/etc/resolv.conf", "r"); 295 FILE *fp = fopen("/etc/resolv.conf", "re");
296 if (!fp) { 296 if (!fp) {
297 fprintf(stderr, "Error: cannot access /etc/resolv.conf\n"); 297 fprintf(stderr, "Error: cannot access /etc/resolv.conf\n");
298 exit(1); 298 exit(1);
diff --git a/src/firejail/no_sandbox.c b/src/firejail/no_sandbox.c
index 60a82821e..0e153c47b 100644
--- a/src/firejail/no_sandbox.c
+++ b/src/firejail/no_sandbox.c
@@ -20,6 +20,7 @@
20#include "firejail.h" 20#include "firejail.h"
21#include <sys/types.h> 21#include <sys/types.h>
22#include <sys/stat.h> 22#include <sys/stat.h>
23#include <errno.h>
23#include <unistd.h> 24#include <unistd.h>
24#include <grp.h> 25#include <grp.h>
25 26
@@ -47,7 +48,7 @@ int check_namespace_virt(void) {
47 48
48 // check PID 1 container environment variable 49 // check PID 1 container environment variable
49 EUID_ROOT(); 50 EUID_ROOT();
50 FILE *fp = fopen("/proc/1/environ", "r"); 51 FILE *fp = fopen("/proc/1/environ", "re");
51 if (fp) { 52 if (fp) {
52 int c = 0; 53 int c = 0;
53 while (c != EOF) { 54 while (c != EOF) {
@@ -105,20 +106,15 @@ int check_kernel_procs(void) {
105 // look at the first 10 processes 106 // look at the first 10 processes
106 // if a kernel process is found, return 1 107 // if a kernel process is found, return 1
107 for (i = 1; i <= 10; i++) { 108 for (i = 1; i <= 10; i++) {
108 struct stat s;
109 char *fname; 109 char *fname;
110 if (asprintf(&fname, "/proc/%d/comm", i) == -1) 110 if (asprintf(&fname, "/proc/%d/comm", i) == -1)
111 errExit("asprintf"); 111 errExit("asprintf");
112 if (stat(fname, &s) == -1) {
113 free(fname);
114 continue;
115 }
116 112
117 // open file 113 // open file
118 /* coverity[toctou] */ 114 FILE *fp = fopen(fname, "re");
119 FILE *fp = fopen(fname, "r");
120 if (!fp) { 115 if (!fp) {
121 fwarning("cannot open %s\n", fname); 116 if (errno != ENOENT)
117 fwarning("cannot open %s\n", fname);
122 free(fname); 118 free(fname);
123 continue; 119 continue;
124 } 120 }
diff --git a/src/firejail/preproc.c b/src/firejail/preproc.c
index 7f602545d..1aafd1ca2 100644
--- a/src/firejail/preproc.c
+++ b/src/firejail/preproc.c
@@ -164,7 +164,7 @@ void preproc_clean_run(void) {
164 int max_pids=32769; 164 int max_pids=32769;
165 int start_pid = 100; 165 int start_pid = 100;
166 // extract real max_pids 166 // extract real max_pids
167 FILE *fp = fopen("/proc/sys/kernel/pid_max", "r"); 167 FILE *fp = fopen("/proc/sys/kernel/pid_max", "re");
168 if (fp) { 168 if (fp) {
169 int val; 169 int val;
170 if (fscanf(fp, "%d", &val) == 1) { 170 if (fscanf(fp, "%d", &val) == 1) {
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 2ea32b665..d94e24ef6 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -1691,7 +1691,7 @@ void profile_read(const char *fname) {
1691 } 1691 }
1692 1692
1693 // open profile file: 1693 // open profile file:
1694 FILE *fp = fopen(fname, "r"); 1694 FILE *fp = fopen(fname, "re");
1695 if (fp == NULL) { 1695 if (fp == NULL) {
1696 fprintf(stderr, "Error: cannot open profile file %s\n", fname); 1696 fprintf(stderr, "Error: cannot open profile file %s\n", fname);
1697 exit(1); 1697 exit(1);
diff --git a/src/firejail/protocol.c b/src/firejail/protocol.c
index 926af7967..f21f8c96e 100644
--- a/src/firejail/protocol.c
+++ b/src/firejail/protocol.c
@@ -23,7 +23,7 @@
23 23
24void protocol_filter_save(void) { 24void protocol_filter_save(void) {
25 // save protocol filter configuration in PROTOCOL_CFG 25 // save protocol filter configuration in PROTOCOL_CFG
26 FILE *fp = fopen(RUN_PROTOCOL_CFG, "w"); 26 FILE *fp = fopen(RUN_PROTOCOL_CFG, "wxe");
27 if (!fp) 27 if (!fp)
28 errExit("fopen"); 28 errExit("fopen");
29 fprintf(fp, "%s\n", cfg.protocol); 29 fprintf(fp, "%s\n", cfg.protocol);
@@ -35,7 +35,7 @@ void protocol_filter_load(const char *fname) {
35 assert(fname); 35 assert(fname);
36 36
37 // read protocol filter configuration from PROTOCOL_CFG 37 // read protocol filter configuration from PROTOCOL_CFG
38 FILE *fp = fopen(fname, "r"); 38 FILE *fp = fopen(fname, "re");
39 if (!fp) 39 if (!fp)
40 return; 40 return;
41 41
diff --git a/src/firejail/pulseaudio.c b/src/firejail/pulseaudio.c
index 4b9203c36..97c022bad 100644
--- a/src/firejail/pulseaudio.c
+++ b/src/firejail/pulseaudio.c
@@ -106,7 +106,7 @@ void pulseaudio_init(void) {
106 errExit("asprintf"); 106 errExit("asprintf");
107 if (copy_file(PULSE_CLIENT_SYSCONF, pulsecfg, -1, -1, 0644)) // root needed 107 if (copy_file(PULSE_CLIENT_SYSCONF, pulsecfg, -1, -1, 0644)) // root needed
108 errExit("copy_file"); 108 errExit("copy_file");
109 FILE *fp = fopen(pulsecfg, "a"); 109 FILE *fp = fopen(pulsecfg, "ae");
110 if (!fp) 110 if (!fp)
111 errExit("fopen"); 111 errExit("fopen");
112 fprintf(fp, "%s", "\nenable-shm = no\n"); 112 fprintf(fp, "%s", "\nenable-shm = no\n");
diff --git a/src/firejail/restrict_users.c b/src/firejail/restrict_users.c
index a0ca4c02c..e173c9888 100644
--- a/src/firejail/restrict_users.c
+++ b/src/firejail/restrict_users.c
@@ -183,10 +183,10 @@ static void sanitize_passwd(void) {
183 183
184 // open files 184 // open files
185 /* coverity[toctou] */ 185 /* coverity[toctou] */
186 fpin = fopen("/etc/passwd", "r"); 186 fpin = fopen("/etc/passwd", "re");
187 if (!fpin) 187 if (!fpin)
188 goto errout; 188 goto errout;
189 fpout = fopen(RUN_PASSWD_FILE, "w"); 189 fpout = fopen(RUN_PASSWD_FILE, "we");
190 if (!fpout) 190 if (!fpout)
191 goto errout; 191 goto errout;
192 192
@@ -318,10 +318,10 @@ static void sanitize_group(void) {
318 318
319 // open files 319 // open files
320 /* coverity[toctou] */ 320 /* coverity[toctou] */
321 fpin = fopen("/etc/group", "r"); 321 fpin = fopen("/etc/group", "re");
322 if (!fpin) 322 if (!fpin)
323 goto errout; 323 goto errout;
324 fpout = fopen(RUN_GROUP_FILE, "w"); 324 fpout = fopen(RUN_GROUP_FILE, "we");
325 if (!fpout) 325 if (!fpout)
326 goto errout; 326 goto errout;
327 327
diff --git a/src/firejail/restricted_shell.c b/src/firejail/restricted_shell.c
index ae453f4f1..ed66903b5 100644
--- a/src/firejail/restricted_shell.c
+++ b/src/firejail/restricted_shell.c
@@ -32,7 +32,7 @@ int restricted_shell(const char *user) {
32 char *fname; 32 char *fname;
33 if (asprintf(&fname, "%s/login.users", SYSCONFDIR) == -1) 33 if (asprintf(&fname, "%s/login.users", SYSCONFDIR) == -1)
34 errExit("asprintf"); 34 errExit("asprintf");
35 FILE *fp = fopen(fname, "r"); 35 FILE *fp = fopen(fname, "re");
36 free(fname); 36 free(fname);
37 if (fp == NULL) 37 if (fp == NULL)
38 return 0; 38 return 0;
@@ -96,7 +96,7 @@ int restricted_shell(const char *user) {
96 fullargv[i] = ptr; 96 fullargv[i] = ptr;
97#ifdef DEBUG_RESTRICTED_SHELL 97#ifdef DEBUG_RESTRICTED_SHELL
98 {EUID_ROOT(); 98 {EUID_ROOT();
99 FILE *fp = fopen("/firelog", "a"); 99 FILE *fp = fopen("/firelog", "ae");
100 if (fp) { 100 if (fp) {
101 fprintf(fp, "i %d ptr #%s#\n", i, fullargv[i]); 101 fprintf(fp, "i %d ptr #%s#\n", i, fullargv[i]);
102 fclose(fp); 102 fclose(fp);
diff --git a/src/firejail/run_files.c b/src/firejail/run_files.c
index cd44f745f..c28c3e01b 100644
--- a/src/firejail/run_files.c
+++ b/src/firejail/run_files.c
@@ -101,7 +101,7 @@ void set_name_run_file(pid_t pid) {
101 errExit("asprintf"); 101 errExit("asprintf");
102 102
103 // the file is deleted first 103 // the file is deleted first
104 FILE *fp = fopen(fname, "w"); 104 FILE *fp = fopen(fname, "we");
105 if (!fp) { 105 if (!fp) {
106 fprintf(stderr, "Error: cannot create %s\n", fname); 106 fprintf(stderr, "Error: cannot create %s\n", fname);
107 exit(1); 107 exit(1);
@@ -120,7 +120,7 @@ void set_x11_run_file(pid_t pid, int display) {
120 errExit("asprintf"); 120 errExit("asprintf");
121 121
122 // the file is deleted first 122 // the file is deleted first
123 FILE *fp = fopen(fname, "w"); 123 FILE *fp = fopen(fname, "we");
124 if (!fp) { 124 if (!fp) {
125 fprintf(stderr, "Error: cannot create %s\n", fname); 125 fprintf(stderr, "Error: cannot create %s\n", fname);
126 exit(1); 126 exit(1);
@@ -139,7 +139,7 @@ void set_profile_run_file(pid_t pid, const char *fname) {
139 139
140 EUID_ROOT(); 140 EUID_ROOT();
141 // the file is deleted first 141 // the file is deleted first
142 FILE *fp = fopen(runfile, "w"); 142 FILE *fp = fopen(runfile, "we");
143 if (!fp) { 143 if (!fp) {
144 fprintf(stderr, "Error: cannot create %s\n", runfile); 144 fprintf(stderr, "Error: cannot create %s\n", runfile);
145 exit(1); 145 exit(1);
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 3af828ede..2c751809e 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -67,7 +67,7 @@ static void sandbox_handler(int sig){
67 if (asprintf(&monfile, "/proc/%d/cmdline", monitored_pid) == -1) 67 if (asprintf(&monfile, "/proc/%d/cmdline", monitored_pid) == -1)
68 errExit("asprintf"); 68 errExit("asprintf");
69 while (monsec) { 69 while (monsec) {
70 FILE *fp = fopen(monfile, "r"); 70 FILE *fp = fopen(monfile, "re");
71 if (!fp) 71 if (!fp)
72 break; 72 break;
73 73
@@ -162,7 +162,7 @@ static void save_nogroups(void) {
162 if (arg_nogroups == 0) 162 if (arg_nogroups == 0)
163 return; 163 return;
164 164
165 FILE *fp = fopen(RUN_GROUPS_CFG, "w"); 165 FILE *fp = fopen(RUN_GROUPS_CFG, "wxe");
166 if (fp) { 166 if (fp) {
167 fprintf(fp, "\n"); 167 fprintf(fp, "\n");
168 SET_PERMS_STREAM(fp, 0, 0, 0644); // assume mode 0644 168 SET_PERMS_STREAM(fp, 0, 0, 0644); // assume mode 0644
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c
index 785c29517..9670fe816 100644
--- a/src/firejail/seccomp.c
+++ b/src/firejail/seccomp.c
@@ -86,7 +86,7 @@ int seccomp_install_filters(void) {
86static void seccomp_save_file_list(const char *fname) { 86static void seccomp_save_file_list(const char *fname) {
87 assert(fname); 87 assert(fname);
88 88
89 FILE *fp = fopen(RUN_SECCOMP_LIST, "a+"); 89 FILE *fp = fopen(RUN_SECCOMP_LIST, "ae");
90 if (!fp) 90 if (!fp)
91 errExit("fopen"); 91 errExit("fopen");
92 92
@@ -99,7 +99,7 @@ static void seccomp_save_file_list(const char *fname) {
99#define MAXBUF 4096 99#define MAXBUF 4096
100static int load_file_list_flag = 0; 100static int load_file_list_flag = 0;
101void seccomp_load_file_list(void) { 101void seccomp_load_file_list(void) {
102 FILE *fp = fopen(RUN_SECCOMP_LIST, "r"); 102 FILE *fp = fopen(RUN_SECCOMP_LIST, "re");
103 if (!fp) 103 if (!fp)
104 return; // no seccomp configuration whatsoever 104 return; // no seccomp configuration whatsoever
105 105
@@ -122,7 +122,7 @@ int seccomp_load(const char *fname) {
122 assert(fname); 122 assert(fname);
123 123
124 // open filter file 124 // open filter file
125 int fd = open(fname, O_RDONLY); 125 int fd = open(fname, O_RDONLY|O_CLOEXEC);
126 if (fd == -1) 126 if (fd == -1)
127 goto errexit; 127 goto errexit;
128 128
@@ -438,7 +438,7 @@ void seccomp_print_filter(pid_t pid) {
438 if (stat(fname, &s) == -1) 438 if (stat(fname, &s) == -1)
439 goto errexit; 439 goto errexit;
440 440
441 FILE *fp = fopen(fname, "r"); 441 FILE *fp = fopen(fname, "re");
442 if (!fp) 442 if (!fp)
443 goto errexit; 443 goto errexit;
444 free(fname); 444 free(fname);
diff --git a/src/firejail/shutdown.c b/src/firejail/shutdown.c
index 8fb03d0a6..fbfe1765b 100644
--- a/src/firejail/shutdown.c
+++ b/src/firejail/shutdown.c
@@ -64,7 +64,7 @@ void shut(pid_t pid) {
64 monsec--; 64 monsec--;
65 65
66 EUID_ROOT(); 66 EUID_ROOT();
67 FILE *fp = fopen(monfile, "r"); 67 FILE *fp = fopen(monfile, "re");
68 EUID_USER(); 68 EUID_USER();
69 if (!fp) { 69 if (!fp) {
70 killdone = 1; 70 killdone = 1;
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 2ad85acd6..2c985c0d6 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -298,14 +298,14 @@ int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, m
298 assert(destname); 298 assert(destname);
299 299
300 // open source 300 // open source
301 int src = open(srcname, O_RDONLY); 301 int src = open(srcname, O_RDONLY|O_CLOEXEC);
302 if (src < 0) { 302 if (src < 0) {
303 fwarning("cannot open source file %s, file not copied\n", srcname); 303 fwarning("cannot open source file %s, file not copied\n", srcname);
304 return -1; 304 return -1;
305 } 305 }
306 306
307 // open destination 307 // open destination
308 int dst = open(destname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 308 int dst = open(destname, O_CREAT|O_WRONLY|O_TRUNC|O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
309 if (dst < 0) { 309 if (dst < 0) {
310 fwarning("cannot open destination file %s, file not copied\n", destname); 310 fwarning("cannot open destination file %s, file not copied\n", destname);
311 close(src); 311 close(src);
@@ -348,7 +348,7 @@ void copy_file_as_user(const char *srcname, const char *destname, uid_t uid, gid
348 348
349void copy_file_from_user_to_root(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode) { 349void copy_file_from_user_to_root(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode) {
350 // open destination 350 // open destination
351 int dst = open(destname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 351 int dst = open(destname, O_CREAT|O_WRONLY|O_TRUNC|O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
352 if (dst < 0) { 352 if (dst < 0) {
353 fwarning("cannot open destination file %s, file not copied\n", destname); 353 fwarning("cannot open destination file %s, file not copied\n", destname);
354 return; 354 return;
@@ -361,7 +361,7 @@ void copy_file_from_user_to_root(const char *srcname, const char *destname, uid_
361 // drop privileges 361 // drop privileges
362 drop_privs(0); 362 drop_privs(0);
363 363
364 int src = open(srcname, O_RDONLY); 364 int src = open(srcname, O_RDONLY|O_CLOEXEC);
365 if (src < 0) { 365 if (src < 0) {
366 fwarning("cannot open source file %s, file not copied\n", srcname); 366 fwarning("cannot open source file %s, file not copied\n", srcname);
367 } else { 367 } else {
@@ -616,7 +616,7 @@ int find_child(pid_t parent, pid_t *child) {
616 perror("asprintf"); 616 perror("asprintf");
617 exit(1); 617 exit(1);
618 } 618 }
619 FILE *fp = fopen(file, "r"); 619 FILE *fp = fopen(file, "re");
620 if (!fp) { 620 if (!fp) {
621 free(file); 621 free(file);
622 continue; 622 continue;
@@ -722,7 +722,7 @@ void update_map(char *mapping, char *map_file) {
722 if (mapping[j] == ',') 722 if (mapping[j] == ',')
723 mapping[j] = '\n'; 723 mapping[j] = '\n';
724 724
725 fd = open(map_file, O_RDWR); 725 fd = open(map_file, O_RDWR|O_CLOEXEC);
726 if (fd == -1) { 726 if (fd == -1) {
727 fprintf(stderr, "Error: cannot open %s: %s\n", map_file, strerror(errno)); 727 fprintf(stderr, "Error: cannot open %s: %s\n", map_file, strerror(errno));
728 exit(EXIT_FAILURE); 728 exit(EXIT_FAILURE);
@@ -742,9 +742,9 @@ void wait_for_other(int fd) {
742 // wait for the parent to be initialized 742 // wait for the parent to be initialized
743 //**************************** 743 //****************************
744 char childstr[BUFLEN + 1]; 744 char childstr[BUFLEN + 1];
745 int newfd = dup(fd); 745 int newfd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
746 if (newfd == -1) 746 if (newfd == -1)
747 errExit("dup"); 747 errExit("fcntl");
748 FILE* stream; 748 FILE* stream;
749 stream = fdopen(newfd, "r"); 749 stream = fdopen(newfd, "r");
750 *childstr = '\0'; 750 *childstr = '\0';
@@ -791,9 +791,9 @@ void wait_for_other(int fd) {
791 791
792void notify_other(int fd) { 792void notify_other(int fd) {
793 FILE* stream; 793 FILE* stream;
794 int newfd = dup(fd); 794 int newfd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
795 if (newfd == -1) 795 if (newfd == -1)
796 errExit("dup"); 796 errExit("fcntl");
797 stream = fdopen(newfd, "w"); 797 stream = fdopen(newfd, "w");
798 fprintf(stream, "arg_noroot=%d\n", arg_noroot); 798 fprintf(stream, "arg_noroot=%d\n", arg_noroot);
799 fflush(stream); 799 fflush(stream);
@@ -811,7 +811,7 @@ uid_t pid_get_uid(pid_t pid) {
811 exit(1); 811 exit(1);
812 } 812 }
813 EUID_ROOT(); // grsecurity fix 813 EUID_ROOT(); // grsecurity fix
814 FILE *fp = fopen(file, "r"); 814 FILE *fp = fopen(file, "re");
815 if (!fp) { 815 if (!fp) {
816 free(file); 816 free(file);
817 fprintf(stderr, "Error: cannot open /proc file\n"); 817 fprintf(stderr, "Error: cannot open /proc file\n");
@@ -1021,8 +1021,7 @@ void create_empty_file_as_root(const char *fname, mode_t mode) {
1021 if (arg_debug) 1021 if (arg_debug)
1022 printf("Creating empty %s file\n", fname); 1022 printf("Creating empty %s file\n", fname);
1023 1023
1024 /* coverity[toctou] */ 1024 FILE *fp = fopen(fname, "wxe");
1025 FILE *fp = fopen(fname, "w");
1026 if (!fp) 1025 if (!fp)
1027 errExit("fopen"); 1026 errExit("fopen");
1028 SET_PERMS_STREAM(fp, 0, 0, mode); 1027 SET_PERMS_STREAM(fp, 0, 0, mode);
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index 1dabf272e..c0587ffc1 100644
--- a/src/firejail/x11.c
+++ b/src/firejail/x11.c
@@ -84,7 +84,7 @@ int x11_display(void) {
84static int x11_abstract_sockets_present(void) { 84static int x11_abstract_sockets_present(void) {
85 85
86 EUID_ROOT(); // grsecurity fix 86 EUID_ROOT(); // grsecurity fix
87 FILE *fp = fopen("/proc/net/unix", "r"); 87 FILE *fp = fopen("/proc/net/unix", "re");
88 if (!fp) 88 if (!fp)
89 errExit("fopen"); 89 errExit("fopen");
90 EUID_USER(); 90 EUID_USER();
@@ -1363,7 +1363,7 @@ void fs_x11(void) {
1363 fs_logger("tmpfs /tmp/.X11-unix"); 1363 fs_logger("tmpfs /tmp/.X11-unix");
1364 1364
1365 // create an empty root-owned file which will have the desired socket bind-mounted over it 1365 // create an empty root-owned file which will have the desired socket bind-mounted over it
1366 int fd = open(x11file, O_RDONLY|O_CREAT|O_EXCL, S_IRUSR | S_IWUSR); 1366 int fd = open(x11file, O_RDONLY|O_CREAT|O_EXCL|O_CLOEXEC, S_IRUSR | S_IWUSR);
1367 if (fd < 0) 1367 if (fd < 0)
1368 errExit(x11file); 1368 errExit(x11file);
1369 close(fd); 1369 close(fd);