aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2016-08-24 21:34:49 -0400
committerLibravatar GitHub <noreply@github.com>2016-08-24 21:34:49 -0400
commit0ecf71a884ac1424bd458df914aed0e837e3cfc0 (patch)
tree88bf6dd701767267ac564c008335e728a9ab727d
parent0.9.42~2 testing (diff)
parenttighten security (diff)
downloadfirejail-0ecf71a884ac1424bd458df914aed0e837e3cfc0.tar.gz
firejail-0ecf71a884ac1424bd458df914aed0e837e3cfc0.tar.zst
firejail-0ecf71a884ac1424bd458df914aed0e837e3cfc0.zip
Merge pull request #743 from manevich/security
additional batch of chown/chmod changes
-rw-r--r--src/firejail/bandwidth.c15
-rw-r--r--src/firejail/cgroup.c3
-rw-r--r--src/firejail/cpu.c5
-rw-r--r--src/firejail/firejail.h21
-rw-r--r--src/firejail/fs.c9
-rw-r--r--src/firejail/fs_bin.c9
-rw-r--r--src/firejail/fs_dev.c62
-rw-r--r--src/firejail/fs_etc.c8
-rw-r--r--src/firejail/fs_home.c28
-rw-r--r--src/firejail/fs_hostname.c28
-rw-r--r--src/firejail/fs_logger.c6
-rw-r--r--src/firejail/fs_mkdir.c7
-rw-r--r--src/firejail/fs_trace.c14
-rw-r--r--src/firejail/fs_var.c23
-rw-r--r--src/firejail/fs_whitelist.c8
-rw-r--r--src/firejail/main.c20
-rw-r--r--src/firejail/protocol.c8
-rw-r--r--src/firejail/pulseaudio.c5
-rw-r--r--src/firejail/restrict_users.c14
-rw-r--r--src/firejail/sandbox.c3
-rw-r--r--src/firejail/seccomp.c3
-rw-r--r--src/firejail/x11.c8
22 files changed, 95 insertions, 212 deletions
diff --git a/src/firejail/bandwidth.c b/src/firejail/bandwidth.c
index 5ff67b644..22be5b23c 100644
--- a/src/firejail/bandwidth.c
+++ b/src/firejail/bandwidth.c
@@ -130,14 +130,8 @@ static void bandwidth_create_run_file(pid_t pid) {
130 /* coverity[toctou] */ 130 /* coverity[toctou] */
131 FILE *fp = fopen(fname, "w"); 131 FILE *fp = fopen(fname, "w");
132 if (fp) { 132 if (fp) {
133 SET_PERMS_STREAM(fp, 0, 0, 0644);
133 fclose(fp); 134 fclose(fp);
134
135 /* coverity[toctou] */
136 if (chmod(fname, 0644) == -1)
137 errExit("chmod");
138 /* coverity[toctou] */
139 if (chown(fname, 0, 0) == -1)
140 errExit("chown");
141 } 135 }
142 else { 136 else {
143 fprintf(stderr, "Error: cannot create bandwidth file\n"); 137 fprintf(stderr, "Error: cannot create bandwidth file\n");
@@ -180,12 +174,9 @@ void network_set_run_file(pid_t pid) {
180 fprintf(fp, "%s:%s\n", cfg.bridge2.dev, cfg.bridge2.devsandbox); 174 fprintf(fp, "%s:%s\n", cfg.bridge2.dev, cfg.bridge2.devsandbox);
181 if (cfg.bridge3.configured) 175 if (cfg.bridge3.configured)
182 fprintf(fp, "%s:%s\n", cfg.bridge3.dev, cfg.bridge3.devsandbox); 176 fprintf(fp, "%s:%s\n", cfg.bridge3.dev, cfg.bridge3.devsandbox);
183 fclose(fp);
184 177
185 if (chmod(fname, 0644) == -1) 178 SET_PERMS_STREAM(fp, 0, 0, 0644);
186 errExit("chmod"); 179 fclose(fp);
187 if (chown(fname, 0, 0) == -1)
188 errExit("chown");
189 } 180 }
190 else { 181 else {
191 fprintf(stderr, "Error: cannot create network map file\n"); 182 fprintf(stderr, "Error: cannot create network map file\n");
diff --git a/src/firejail/cgroup.c b/src/firejail/cgroup.c
index ebd87f0d2..d9c7af9cf 100644
--- a/src/firejail/cgroup.c
+++ b/src/firejail/cgroup.c
@@ -30,10 +30,9 @@ void save_cgroup(void) {
30 if (fp) { 30 if (fp) {
31 fprintf(fp, "%s", cfg.cgroup); 31 fprintf(fp, "%s", cfg.cgroup);
32 fflush(0); 32 fflush(0);
33 SET_PERMS_STREAM(fp, 0, 0, 0644);
33 if (fclose(fp)) 34 if (fclose(fp))
34 goto errout; 35 goto errout;
35 if (chown(RUN_CGROUP_CFG, 0, 0) < 0)
36 errExit("chown");
37 } 36 }
38 else 37 else
39 goto errout; 38 goto errout;
diff --git a/src/firejail/cpu.c b/src/firejail/cpu.c
index 1802ad5e1..cfb03e5fc 100644
--- a/src/firejail/cpu.c
+++ b/src/firejail/cpu.c
@@ -78,11 +78,8 @@ void save_cpu(void) {
78 FILE *fp = fopen(RUN_CPU_CFG, "w"); 78 FILE *fp = fopen(RUN_CPU_CFG, "w");
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 fclose(fp); 82 fclose(fp);
82 if (chmod(RUN_CPU_CFG, 0600) < 0)
83 errExit("chmod");
84 if (chown(RUN_CPU_CFG, 0, 0) < 0)
85 errExit("chown");
86 } 83 }
87 else { 84 else {
88 fprintf(stderr, "Error: cannot save cpu affinity mask\n"); 85 fprintf(stderr, "Error: cannot save cpu affinity mask\n");
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 755ed4979..7be04f782 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -100,6 +100,27 @@
100 ASSERT_PERMS_FD(fd, uid, gid, (mode));\ 100 ASSERT_PERMS_FD(fd, uid, gid, (mode));\
101 } while (0) 101 } while (0)
102 102
103#define SET_PERMS_FD(fd, uid, gid, mode) \
104 do { \
105 if (fchmod(fd, (mode)) == -1) errExit("chmod");\
106 if (fchown(fd, uid, gid) == -1) errExit("chown");\
107 } while (0)
108#define SET_PERMS_STREAM(stream, uid, gid, mode) \
109 do { \
110 int fd = fileno(stream);\
111 if (fd == -1) errExit("fileno");\
112 SET_PERMS_FD(fd, uid, gid, (mode));\
113 } while (0)
114#define SET_PERMS_STREAM_NOERR(stream, uid, gid, mode) \
115 do { \
116 int fd = fileno(stream);\
117 if (fd == -1) continue;\
118 int rv = fchmod(fd, (mode));\
119 (void) rv;\
120 rv = fchown(fd, uid, gid);\
121 (void) rv;\
122 } while (0)
123
103// main.c 124// main.c
104typedef struct bridge_t { 125typedef struct bridge_t {
105 // on the host 126 // on the host
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 21ab56bd8..27c69d0e1 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -60,14 +60,7 @@ static void create_empty_file(void) {
60 if (!fp) 60 if (!fp)
61 errExit("fopen"); 61 errExit("fopen");
62 62
63 int fd = fileno(fp); 63 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR);
64 if (fd == -1)
65 errExit("fileno");
66 if (fchown(fd, 0, 0) < 0)
67 errExit("chown");
68 if (fchmod(fd, S_IRUSR) < 0)
69 errExit("chown");
70
71 fclose(fp); 64 fclose(fp);
72 } 65 }
73} 66}
diff --git a/src/firejail/fs_bin.c b/src/firejail/fs_bin.c
index 6bd407346..b9d8614d4 100644
--- a/src/firejail/fs_bin.c
+++ b/src/firejail/fs_bin.c
@@ -203,14 +203,9 @@ void fs_private_bin_list(void) {
203 203
204 // create /tmp/firejail/mnt/bin directory 204 // create /tmp/firejail/mnt/bin directory
205 fs_build_mnt_dir(); 205 fs_build_mnt_dir();
206 int rv = mkdir(RUN_BIN_DIR, 0755); 206 if (mkdir(RUN_BIN_DIR, 0755) == -1)
207 if (rv == -1)
208 errExit("mkdir"); 207 errExit("mkdir");
209 if (chown(RUN_BIN_DIR, 0, 0) < 0) 208 ASSERT_PERMS(RUN_BIN_DIR, 0, 0, 0755);
210 errExit("chown");
211 if (chmod(RUN_BIN_DIR, 0755) < 0)
212 errExit("chmod");
213
214 209
215 // copy the list of files in the new etc directory 210 // copy the list of files in the new etc directory
216 // using a new child process without root privileges 211 // using a new child process without root privileges
diff --git a/src/firejail/fs_dev.c b/src/firejail/fs_dev.c
index c7a27115f..571848dec 100644
--- a/src/firejail/fs_dev.c
+++ b/src/firejail/fs_dev.c
@@ -32,15 +32,11 @@
32 32
33static void create_char_dev(const char *path, mode_t mode, int major, int minor) { 33static void create_char_dev(const char *path, mode_t mode, int major, int minor) {
34 dev_t dev = makedev(major, minor); 34 dev_t dev = makedev(major, minor);
35 int rv = mknod(path, S_IFCHR | mode, dev); 35 if (mknod(path, S_IFCHR | mode, dev) == -1)
36 if (rv == -1)
37 goto errexit; 36 goto errexit;
38
39
40 if (chmod(path, mode) < 0) 37 if (chmod(path, mode) < 0)
41 goto errexit; 38 goto errexit;
42 if (chown(path, 0, 0) < 0) 39 ASSERT_PERMS(path, 0, 0, mode);
43 goto errexit;
44 40
45 return; 41 return;
46 42
@@ -78,14 +74,9 @@ void fs_private_dev(void){
78 // create DRI_DIR 74 // create DRI_DIR
79 fs_build_mnt_dir(); 75 fs_build_mnt_dir();
80 if (have_dri) { 76 if (have_dri) {
81 /* coverity[toctou] */ 77 if (mkdir(RUN_DRI_DIR, 0755) == -1)
82 rv = mkdir(RUN_DRI_DIR, 0755);
83 if (rv == -1)
84 errExit("mkdir"); 78 errExit("mkdir");
85 if (chown(RUN_DRI_DIR, 0, 0) < 0) 79 ASSERT_PERMS(RUN_DRI_DIR, 0, 0, 0755);
86 errExit("chown");
87 if (chmod(RUN_DRI_DIR, 0755) < 0)
88 errExit("chmod");
89 80
90 // keep a copy of /dev/dri under DRI_DIR 81 // keep a copy of /dev/dri under DRI_DIR
91 if (mount("/dev/dri", RUN_DRI_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) 82 if (mount("/dev/dri", RUN_DRI_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
@@ -94,14 +85,9 @@ void fs_private_dev(void){
94 85
95 // create SND_DIR 86 // create SND_DIR
96 if (have_snd) { 87 if (have_snd) {
97 /* coverity[toctou] */ 88 if (mkdir(RUN_SND_DIR, 0755) == -1)
98 rv = mkdir(RUN_SND_DIR, 0755);
99 if (rv == -1)
100 errExit("mkdir"); 89 errExit("mkdir");
101 if (chown(RUN_SND_DIR, 0, 0) < 0) 90 ASSERT_PERMS(RUN_SND_DIR, 0, 0, 0755);
102 errExit("chown");
103 if (chmod(RUN_SND_DIR, 0755) < 0)
104 errExit("chmod");
105 91
106 // keep a copy of /dev/dri under DRI_DIR 92 // keep a copy of /dev/dri under DRI_DIR
107 if (mount("/dev/snd", RUN_SND_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) 93 if (mount("/dev/snd", RUN_SND_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
@@ -143,13 +129,9 @@ void fs_private_dev(void){
143 // bring back the /dev/snd directory 129 // bring back the /dev/snd directory
144 if (have_snd) { 130 if (have_snd) {
145 /* coverity[toctou] */ 131 /* coverity[toctou] */
146 rv = mkdir("/dev/snd", 0755); 132 if (mkdir("/dev/snd", 0755) == -1)
147 if (rv == -1)
148 errExit("mkdir"); 133 errExit("mkdir");
149 if (chown("/dev/snd", 0, 0) < 0) 134 ASSERT_PERMS("/dev/snd", 0, 0, 0755);
150 errExit("chown");
151 if (chmod("/dev/snd",0755) < 0)
152 errExit("chmod");
153 if (mount(RUN_SND_DIR, "/dev/snd", NULL, MS_BIND|MS_REC, NULL) < 0) 135 if (mount(RUN_SND_DIR, "/dev/snd", NULL, MS_BIND|MS_REC, NULL) < 0)
154 errExit("mounting /dev/snd"); 136 errExit("mounting /dev/snd");
155 fs_logger("whitelist /dev/snd"); 137 fs_logger("whitelist /dev/snd");
@@ -157,14 +139,9 @@ void fs_private_dev(void){
157 139
158 // bring back the /dev/dri directory 140 // bring back the /dev/dri directory
159 if (have_dri) { 141 if (have_dri) {
160 /* coverity[toctou] */ 142 if (mkdir("/dev/dri", 0755) == -1)
161 rv = mkdir("/dev/dri", 0755);
162 if (rv == -1)
163 errExit("mkdir"); 143 errExit("mkdir");
164 if (chown("/dev/dri", 0, 0) < 0) 144 ASSERT_PERMS("/dev/dri", 0, 0, 0755);
165 errExit("chown");
166 if (chmod("/dev/dri",0755) < 0)
167 errExit("chmod");
168 if (mount(RUN_DRI_DIR, "/dev/dri", NULL, MS_BIND|MS_REC, NULL) < 0) 145 if (mount(RUN_DRI_DIR, "/dev/dri", NULL, MS_BIND|MS_REC, NULL) < 0)
169 errExit("mounting /dev/dri"); 146 errExit("mounting /dev/dri");
170 fs_logger("whitelist /dev/dri"); 147 fs_logger("whitelist /dev/dri");
@@ -173,13 +150,12 @@ void fs_private_dev(void){
173 // create /dev/shm 150 // create /dev/shm
174 if (arg_debug) 151 if (arg_debug)
175 printf("Create /dev/shm directory\n"); 152 printf("Create /dev/shm directory\n");
176 rv = mkdir("/dev/shm", 01777); 153 if (mkdir("/dev/shm", 01777) == -1)
177 if (rv == -1)
178 errExit("mkdir"); 154 errExit("mkdir");
179 if (chown("/dev/shm", 0, 0) < 0) 155 // mkdir sets only the file permission bits
180 errExit("chown");
181 if (chmod("/dev/shm", 01777) < 0) 156 if (chmod("/dev/shm", 01777) < 0)
182 errExit("chmod"); 157 errExit("chmod");
158 ASSERT_PERMS("/dev/shm", 0, 0, 01777);
183 fs_logger("mkdir /dev/shm"); 159 fs_logger("mkdir /dev/shm");
184 160
185 // create devices 161 // create devices
@@ -201,13 +177,9 @@ void fs_private_dev(void){
201#endif 177#endif
202 178
203 // pseudo-terminal 179 // pseudo-terminal
204 rv = mkdir("/dev/pts", 0755); 180 if (mkdir("/dev/pts", 0755) == -1)
205 if (rv == -1)
206 errExit("mkdir"); 181 errExit("mkdir");
207 if (chown("/dev/pts", 0, 0) < 0) 182 ASSERT_PERMS("/dev/pts", 0, 0, 0755);
208 errExit("chown");
209 if (chmod("/dev/pts", 0755) < 0)
210 errExit("chmod");
211 fs_logger("mkdir /dev/pts"); 183 fs_logger("mkdir /dev/pts");
212 create_char_dev("/dev/pts/ptmx", 0666, 5, 2); //"mknod -m 666 /dev/pts/ptmx c 5 2"); 184 create_char_dev("/dev/pts/ptmx", 0666, 5, 2); //"mknod -m 666 /dev/pts/ptmx c 5 2");
213 fs_logger("mknod /dev/pts/ptmx"); 185 fs_logger("mknod /dev/pts/ptmx");
@@ -258,10 +230,10 @@ void fs_dev_shm(void) {
258 // create directory 230 // create directory
259 if (mkdir(lnk, 01777)) 231 if (mkdir(lnk, 01777))
260 errExit("mkdir"); 232 errExit("mkdir");
261 if (chown(lnk, 0, 0)) 233 // mkdir sets only the file permission bits
262 errExit("chown");
263 if (chmod(lnk, 01777)) 234 if (chmod(lnk, 01777))
264 errExit("chmod"); 235 errExit("chmod");
236 ASSERT_PERMS(lnk, 0, 0, 01777);
265 } 237 }
266 if (arg_debug) 238 if (arg_debug)
267 printf("Mounting tmpfs on %s on behalf of /dev/shm\n", lnk); 239 printf("Mounting tmpfs on %s on behalf of /dev/shm\n", lnk);
diff --git a/src/firejail/fs_etc.c b/src/firejail/fs_etc.c
index 6b9a4395b..d5b348ee2 100644
--- a/src/firejail/fs_etc.c
+++ b/src/firejail/fs_etc.c
@@ -130,13 +130,9 @@ void fs_private_etc_list(void) {
130 130
131 // create /tmp/firejail/mnt/etc directory 131 // create /tmp/firejail/mnt/etc directory
132 fs_build_mnt_dir(); 132 fs_build_mnt_dir();
133 int rv = mkdir(RUN_ETC_DIR, 0755); 133 if (mkdir(RUN_ETC_DIR, 0755) == -1)
134 if (rv == -1)
135 errExit("mkdir"); 134 errExit("mkdir");
136 if (chown(RUN_ETC_DIR, 0, 0) < 0) 135 ASSERT_PERMS(RUN_ETC_DIR, 0, 0, 0755);
137 errExit("chown");
138 if (chmod(RUN_ETC_DIR, 0755) < 0)
139 errExit("chmod");
140 fs_logger("tmpfs /etc"); 136 fs_logger("tmpfs /etc");
141 137
142 fs_logger_print(); // save the current log 138 fs_logger_print(); // save the current log
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index 75d69e021..85fa244be 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -51,11 +51,8 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
51 FILE *fp = fopen(fname, "w"); 51 FILE *fp = fopen(fname, "w");
52 if (fp) { 52 if (fp) {
53 fprintf(fp, "\n"); 53 fprintf(fp, "\n");
54 SET_PERMS_STREAM(fp, u, g, S_IRUSR | S_IWUSR);
54 fclose(fp); 55 fclose(fp);
55 if (chown(fname, u, g) == -1)
56 errExit("chown");
57 if (chmod(fname, S_IRUSR | S_IWUSR) < 0)
58 errExit("chown");
59 fs_logger2("touch", fname); 56 fs_logger2("touch", fname);
60 } 57 }
61 } 58 }
@@ -80,11 +77,8 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
80 FILE *fp = fopen(fname, "w"); 77 FILE *fp = fopen(fname, "w");
81 if (fp) { 78 if (fp) {
82 fprintf(fp, "\n"); 79 fprintf(fp, "\n");
80 SET_PERMS_STREAM(fp, u, g, S_IRUSR | S_IWUSR);
83 fclose(fp); 81 fclose(fp);
84 if (chown(fname, u, g) == -1)
85 errExit("chown");
86 if (chmod(fname, S_IRUSR | S_IWUSR) < 0)
87 errExit("chown");
88 fs_logger2("touch", fname); 82 fs_logger2("touch", fname);
89 } 83 }
90 } 84 }
@@ -177,17 +171,12 @@ static void copy_xauthority(void) {
177 char *dest; 171 char *dest;
178 if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1) 172 if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1)
179 errExit("asprintf"); 173 errExit("asprintf");
180 int rv = copy_file(src, dest, -1, -1, 0600); 174 // copy, set permissions and ownership
175 int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR);
181 if (rv) 176 if (rv)
182 fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); 177 fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n");
183 else { 178 else {
184 fs_logger2("clone", dest); 179 fs_logger2("clone", dest);
185
186 // set permissions and ownership
187 if (chown(dest, getuid(), getgid()) < 0)
188 errExit("chown");
189 if (chmod(dest, S_IRUSR | S_IWUSR) < 0)
190 errExit("chmod");
191 } 180 }
192 181
193 // delete the temporary file 182 // delete the temporary file
@@ -200,17 +189,12 @@ static void copy_asoundrc(void) {
200 char *dest; 189 char *dest;
201 if (asprintf(&dest, "%s/.asoundrc", cfg.homedir) == -1) 190 if (asprintf(&dest, "%s/.asoundrc", cfg.homedir) == -1)
202 errExit("asprintf"); 191 errExit("asprintf");
203 int rv = copy_file(src, dest, -1 , -1, 0644); 192 // copy, set permissions and ownership
193 int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR);
204 if (rv) 194 if (rv)
205 fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); 195 fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n");
206 else { 196 else {
207 fs_logger2("clone", dest); 197 fs_logger2("clone", dest);
208
209 // set permissions and ownership
210 if (chown(dest, getuid(), getgid()) < 0)
211 errExit("chown");
212 if (chmod(dest, S_IRUSR | S_IWUSR) < 0)
213 errExit("chmod");
214 } 198 }
215 199
216 // delete the temporary file 200 // delete the temporary file
diff --git a/src/firejail/fs_hostname.c b/src/firejail/fs_hostname.c
index aa391c0cb..87d3742e4 100644
--- a/src/firejail/fs_hostname.c
+++ b/src/firejail/fs_hostname.c
@@ -40,14 +40,10 @@ void fs_hostname(const char *hostname) {
40 exit(1); 40 exit(1);
41 } 41 }
42 fprintf(fp, "%s\n", hostname); 42 fprintf(fp, "%s\n", hostname);
43 fclose(fp);
44
45 // mode and owner 43 // mode and owner
46 if (chown(RUN_HOSTNAME_FILE, 0, 0) < 0) 44 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
47 errExit("chown"); 45 fclose(fp);
48 if (chmod(RUN_HOSTNAME_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0) 46
49 errExit("chmod");
50
51 // bind-mount the file on top of /etc/hostname 47 // bind-mount the file on top of /etc/hostname
52 if (mount(RUN_HOSTNAME_FILE, "/etc/hostname", NULL, MS_BIND|MS_REC, NULL) < 0) 48 if (mount(RUN_HOSTNAME_FILE, "/etc/hostname", NULL, MS_BIND|MS_REC, NULL) < 0)
53 errExit("mount bind /etc/hostname"); 49 errExit("mount bind /etc/hostname");
@@ -88,13 +84,9 @@ void fs_hostname(const char *hostname) {
88 fprintf(fp2, "%s\n", buf); 84 fprintf(fp2, "%s\n", buf);
89 } 85 }
90 fclose(fp1); 86 fclose(fp1);
91 fclose(fp2);
92
93 // mode and owner 87 // mode and owner
94 if (chown(RUN_HOSTS_FILE, 0, 0) < 0) 88 SET_PERMS_STREAM(fp2, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
95 errExit("chown"); 89 fclose(fp2);
96 if (chmod(RUN_HOSTS_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0)
97 errExit("chmod");
98 90
99 // bind-mount the file on top of /etc/hostname 91 // bind-mount the file on top of /etc/hostname
100 if (mount(RUN_HOSTS_FILE, "/etc/hosts", NULL, MS_BIND|MS_REC, NULL) < 0) 92 if (mount(RUN_HOSTS_FILE, "/etc/hosts", NULL, MS_BIND|MS_REC, NULL) < 0)
@@ -126,13 +118,11 @@ void fs_resolvconf(void) {
126 fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns2)); 118 fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns2));
127 if (cfg.dns3) 119 if (cfg.dns3)
128 fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns3)); 120 fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns3));
129 fclose(fp); 121
130
131 // mode and owner 122 // mode and owner
132 if (chown(RUN_RESOLVCONF_FILE, 0, 0) < 0) 123 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
133 errExit("chown"); 124
134 if (chmod(RUN_RESOLVCONF_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0) 125 fclose(fp);
135 errExit("chmod");
136 126
137 // bind-mount the file on top of /etc/hostname 127 // bind-mount the file on top of /etc/hostname
138 if (mount(RUN_RESOLVCONF_FILE, "/etc/resolv.conf", NULL, MS_BIND|MS_REC, NULL) < 0) 128 if (mount(RUN_RESOLVCONF_FILE, "/etc/resolv.conf", NULL, MS_BIND|MS_REC, NULL) < 0)
diff --git a/src/firejail/fs_logger.c b/src/firejail/fs_logger.c
index 30b0fe438..9f33b36d9 100644
--- a/src/firejail/fs_logger.c
+++ b/src/firejail/fs_logger.c
@@ -97,11 +97,7 @@ void fs_logger_print(void) {
97 perror("fopen"); 97 perror("fopen");
98 return; 98 return;
99 } 99 }
100 100 SET_PERMS_STREAM_NOERR(fp, getuid(), getgid(), 0644);
101 int rv = chown(RUN_FSLOGGER_FILE, getuid(), getgid());
102 (void) rv; // best effort!
103 rv = chmod(RUN_FSLOGGER_FILE, 0644);
104 (void) rv; // best effort!
105 101
106 FsMsg *ptr = head; 102 FsMsg *ptr = head;
107 while (ptr) { 103 while (ptr) {
diff --git a/src/firejail/fs_mkdir.c b/src/firejail/fs_mkdir.c
index 5bc2df2cc..b2a5927e6 100644
--- a/src/firejail/fs_mkdir.c
+++ b/src/firejail/fs_mkdir.c
@@ -119,9 +119,12 @@ void fs_mkfile(const char *name) {
119 if (!fp) 119 if (!fp)
120 fprintf(stderr, "Warning: cannot create %s file\n", expanded); 120 fprintf(stderr, "Warning: cannot create %s file\n", expanded);
121 else { 121 else {
122 fclose(fp); 122 int fd = fileno(fp);
123 int rv = chmod(expanded, 0600); 123 if (fd == -1)
124 errExit("fileno");
125 int rv = fchmod(fd, 0600);
124 (void) rv; 126 (void) rv;
127 fclose(fp);
125 } 128 }
126 exit(0); 129 exit(0);
127 } 130 }
diff --git a/src/firejail/fs_trace.c b/src/firejail/fs_trace.c
index f6ca28227..bab117b7e 100644
--- a/src/firejail/fs_trace.c
+++ b/src/firejail/fs_trace.c
@@ -37,11 +37,8 @@ void fs_trace_preload(void) {
37 FILE *fp = fopen("/etc/ld.so.preload", "w"); 37 FILE *fp = fopen("/etc/ld.so.preload", "w");
38 if (!fp) 38 if (!fp)
39 errExit("fopen"); 39 errExit("fopen");
40 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
40 fclose(fp); 41 fclose(fp);
41 if (chown("/etc/ld.so.preload", 0, 0) < 0)
42 errExit("chown");
43 if (chmod("/etc/ld.so.preload", S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0)
44 errExit("chmod");
45 fs_logger("touch /etc/ld.so.preload"); 42 fs_logger("touch /etc/ld.so.preload");
46 } 43 }
47} 44}
@@ -66,12 +63,9 @@ void fs_trace(void) {
66 } 63 }
67 else 64 else
68 assert(0); 65 assert(0);
69 66
67 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
70 fclose(fp); 68 fclose(fp);
71 if (chown(RUN_LDPRELOAD_FILE, 0, 0) < 0)
72 errExit("chown");
73 if (chmod(RUN_LDPRELOAD_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0)
74 errExit("chmod");
75 69
76 // mount the new preload file 70 // mount the new preload file
77 if (arg_debug) 71 if (arg_debug)
@@ -81,5 +75,3 @@ void fs_trace(void) {
81 fs_logger("create /etc/ld.so.preload"); 75 fs_logger("create /etc/ld.so.preload");
82} 76}
83 77
84
85 \ No newline at end of file
diff --git a/src/firejail/fs_var.c b/src/firejail/fs_var.c
index 1516d684f..a578d04e6 100644
--- a/src/firejail/fs_var.c
+++ b/src/firejail/fs_var.c
@@ -131,22 +131,16 @@ void fs_var_log(void) {
131 // create an empty /var/log/wtmp file 131 // create an empty /var/log/wtmp file
132 /* coverity[toctou] */ 132 /* coverity[toctou] */
133 FILE *fp = fopen("/var/log/wtmp", "w"); 133 FILE *fp = fopen("/var/log/wtmp", "w");
134 SET_PERMS_STREAM(fp, 0, wtmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH);
134 if (fp) 135 if (fp)
135 fclose(fp); 136 fclose(fp);
136 if (chown("/var/log/wtmp", 0, wtmp_group) < 0)
137 errExit("chown");
138 if (chmod("/var/log/wtmp", S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH ) < 0)
139 errExit("chmod");
140 fs_logger("touch /var/log/wtmp"); 137 fs_logger("touch /var/log/wtmp");
141 138
142 // create an empty /var/log/btmp file 139 // create an empty /var/log/btmp file
143 fp = fopen("/var/log/btmp", "w"); 140 fp = fopen("/var/log/btmp", "w");
141 SET_PERMS_STREAM(fp, 0, wtmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP);
144 if (fp) 142 if (fp)
145 fclose(fp); 143 fclose(fp);
146 if (chown("/var/log/btmp", 0, wtmp_group) < 0)
147 errExit("chown");
148 if (chmod("/var/log/btmp", S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP) < 0)
149 errExit("chmod");
150 fs_logger("touch /var/log/btmp"); 144 fs_logger("touch /var/log/btmp");
151 } 145 }
152 else 146 else
@@ -169,11 +163,8 @@ void fs_var_lib(void) {
169 163
170 if (fp) { 164 if (fp) {
171 fprintf(fp, "\n"); 165 fprintf(fp, "\n");
166 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
172 fclose(fp); 167 fclose(fp);
173 if (chown("/var/lib/dhcp/dhcpd.leases", 0, 0) == -1)
174 errExit("chown");
175 if (chmod("/var/lib/dhcp/dhcpd.leases", S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH))
176 errExit("chmod");
177 fs_logger("touch /var/lib/dhcp/dhcpd.leases"); 168 fs_logger("touch /var/lib/dhcp/dhcpd.leases");
178 } 169 }
179 } 170 }
@@ -279,10 +270,9 @@ void fs_var_lock(void) {
279 // create directory 270 // create directory
280 if (mkdir(lnk, S_IRWXU|S_IRWXG|S_IRWXO)) 271 if (mkdir(lnk, S_IRWXU|S_IRWXG|S_IRWXO))
281 errExit("mkdir"); 272 errExit("mkdir");
282 if (chown(lnk, 0, 0))
283 errExit("chown");
284 if (chmod(lnk, S_IRWXU|S_IRWXG|S_IRWXO)) 273 if (chmod(lnk, S_IRWXU|S_IRWXG|S_IRWXO))
285 errExit("chmod"); 274 errExit("chmod");
275 ASSERT_PERMS(lnk, 0, 0, S_IRWXU|S_IRWXG|S_IRWXO);
286 } 276 }
287 if (arg_debug) 277 if (arg_debug)
288 printf("Mounting tmpfs on %s on behalf of /var/lock\n", lnk); 278 printf("Mounting tmpfs on %s on behalf of /var/lock\n", lnk);
@@ -353,11 +343,8 @@ void fs_var_utmp(void) {
353 343
354 // save new utmp file 344 // save new utmp file
355 fwrite(&u_boot, sizeof(u_boot), 1, fp); 345 fwrite(&u_boot, sizeof(u_boot), 1, fp);
346 SET_PERMS_STREAM(fp, 0, utmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH);
356 fclose(fp); 347 fclose(fp);
357 if (chown(RUN_UTMP_FILE, 0, utmp_group) < 0)
358 errExit("chown");
359 if (chmod(RUN_UTMP_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH ) < 0)
360 errExit("chmod");
361 348
362 // mount the new utmp file 349 // mount the new utmp file
363 if (arg_debug) 350 if (arg_debug)
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index 90b91f9dd..33037da29 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -275,18 +275,14 @@ static void whitelist_path(ProfileEntry *entry) {
275 fprintf(stderr, "Error: cannot create empty file in home directory\n"); 275 fprintf(stderr, "Error: cannot create empty file in home directory\n");
276 exit(1); 276 exit(1);
277 } 277 }
278 // set file properties
279 SET_PERMS_STREAM(fp, s.st_uid, s.st_gid, s.st_mode);
278 fclose(fp); 280 fclose(fp);
279 } 281 }
280 else 282 else
281 return; // the file is already present 283 return; // the file is already present
282 } 284 }
283 285
284 // set file properties
285 if (chown(path, s.st_uid, s.st_gid) < 0)
286 errExit("chown");
287 if (chmod(path, s.st_mode) < 0)
288 errExit("chmod");
289
290 // mount 286 // mount
291 if (mount(wfile, path, NULL, MS_BIND|MS_REC, NULL) < 0) 287 if (mount(wfile, path, NULL, MS_BIND|MS_REC, NULL) < 0)
292 errExit("mount bind"); 288 errExit("mount bind");
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 2181a274b..dbb92a899 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -663,14 +663,10 @@ static void set_name_file(pid_t pid) {
663 exit(1); 663 exit(1);
664 } 664 }
665 fprintf(fp, "%s\n", cfg.name); 665 fprintf(fp, "%s\n", cfg.name);
666 fclose(fp); 666
667
668 // mode and ownership 667 // mode and ownership
669 if (chown(fname, 0, 0) == -1) 668 SET_PERMS_STREAM(fp, 0, 0, 0644);
670 errExit("chown"); 669 fclose(fp);
671 if (chmod(fname, 0644) == -1)
672 errExit("chmod");
673
674} 670}
675 671
676static void delete_name_file(pid_t pid) { 672static void delete_name_file(pid_t pid) {
@@ -694,14 +690,10 @@ static void set_x11_file(pid_t pid, int display) {
694 exit(1); 690 exit(1);
695 } 691 }
696 fprintf(fp, "%d\n", display); 692 fprintf(fp, "%d\n", display);
697 fclose(fp); 693
698
699 // mode and ownership 694 // mode and ownership
700 if (chown(fname, 0, 0) == -1) 695 SET_PERMS_STREAM(fp, 0, 0, 0644);
701 errExit("chown"); 696 fclose(fp);
702 if (chmod(fname, 0644) == -1)
703 errExit("chmod");
704
705} 697}
706 698
707static void delete_x11_file(pid_t pid) { 699static void delete_x11_file(pid_t pid) {
diff --git a/src/firejail/protocol.c b/src/firejail/protocol.c
index 7e5ab7dfb..1ef5bf13d 100644
--- a/src/firejail/protocol.c
+++ b/src/firejail/protocol.c
@@ -273,14 +273,8 @@ void protocol_filter_save(void) {
273 if (!fp) 273 if (!fp)
274 errExit("fopen"); 274 errExit("fopen");
275 fprintf(fp, "%s\n", cfg.protocol); 275 fprintf(fp, "%s\n", cfg.protocol);
276 SET_PERMS_STREAM(fp, 0, 0, 0600);
276 fclose(fp); 277 fclose(fp);
277
278 if (chmod(RUN_PROTOCOL_CFG, 0600) < 0)
279 errExit("chmod");
280
281 if (chown(RUN_PROTOCOL_CFG, 0, 0) < 0)
282 errExit("chown");
283
284} 278}
285 279
286void protocol_filter_load(const char *fname) { 280void protocol_filter_load(const char *fname) {
diff --git a/src/firejail/pulseaudio.c b/src/firejail/pulseaudio.c
index dd26d219c..7db8d2c18 100644
--- a/src/firejail/pulseaudio.c
+++ b/src/firejail/pulseaudio.c
@@ -120,11 +120,8 @@ void pulseaudio_init(void) {
120 if (!fp) 120 if (!fp)
121 errExit("fopen"); 121 errExit("fopen");
122 fprintf(fp, "%s", "\nenable-shm = no\n"); 122 fprintf(fp, "%s", "\nenable-shm = no\n");
123 SET_PERMS_STREAM(fp, getuid(), getgid(), 0644);
123 fclose(fp); 124 fclose(fp);
124 if (chmod(pulsecfg, 0644) == -1)
125 errExit("chmod");
126 if (chown(pulsecfg, getuid(), getgid()) == -1)
127 errExit("chown");
128 125
129 // create ~/.config/pulse directory if not present 126 // create ~/.config/pulse directory if not present
130 char *dir1; 127 char *dir1;
diff --git a/src/firejail/restrict_users.c b/src/firejail/restrict_users.c
index de798037f..cb999a4a6 100644
--- a/src/firejail/restrict_users.c
+++ b/src/firejail/restrict_users.c
@@ -187,12 +187,9 @@ static void sanitize_passwd(void) {
187 fprintf(fpout, "%s", buf); 187 fprintf(fpout, "%s", buf);
188 } 188 }
189 fclose(fpin); 189 fclose(fpin);
190 SET_PERMS_STREAM(fpout, 0, 0, 0644);
190 fclose(fpout); 191 fclose(fpout);
191 if (chown(RUN_PASSWD_FILE, 0, 0) == -1) 192
192 errExit("chown");
193 if (chmod(RUN_PASSWD_FILE, 0644) == -1)
194 errExit("chmod");
195
196 // mount-bind tne new password file 193 // mount-bind tne new password file
197 if (mount(RUN_PASSWD_FILE, "/etc/passwd", "none", MS_BIND, "mode=400,gid=0") < 0) 194 if (mount(RUN_PASSWD_FILE, "/etc/passwd", "none", MS_BIND, "mode=400,gid=0") < 0)
198 errExit("mount"); 195 errExit("mount");
@@ -319,12 +316,9 @@ static void sanitize_group(void) {
319 goto errout; 316 goto errout;
320 } 317 }
321 fclose(fpin); 318 fclose(fpin);
319 SET_PERMS_STREAM(fpout, 0, 0, 0644);
322 fclose(fpout); 320 fclose(fpout);
323 if (chown(RUN_GROUP_FILE, 0, 0) == -1) 321
324 errExit("chown");
325 if (chmod(RUN_GROUP_FILE, 0644) == -1)
326 errExit("chmod");
327
328 // mount-bind tne new group file 322 // mount-bind tne new group file
329 if (mount(RUN_GROUP_FILE, "/etc/group", "none", MS_BIND, "mode=400,gid=0") < 0) 323 if (mount(RUN_GROUP_FILE, "/etc/group", "none", MS_BIND, "mode=400,gid=0") < 0)
330 errExit("mount"); 324 errExit("mount");
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 5f845fbd3..9423ae7e0 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -104,9 +104,8 @@ void save_nogroups(void) {
104 FILE *fp = fopen(RUN_GROUPS_CFG, "w"); 104 FILE *fp = fopen(RUN_GROUPS_CFG, "w");
105 if (fp) { 105 if (fp) {
106 fprintf(fp, "\n"); 106 fprintf(fp, "\n");
107 SET_PERMS_STREAM(fp, 0, 0, 0644); // assume mode 0644
107 fclose(fp); 108 fclose(fp);
108 if (chown(RUN_GROUPS_CFG, 0, 0) < 0)
109 errExit("chown");
110 } 109 }
111 else { 110 else {
112 fprintf(stderr, "Error: cannot save nogroups state\n"); 111 fprintf(stderr, "Error: cannot save nogroups state\n");
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c
index 7aaf1a5cd..c2da1168a 100644
--- a/src/firejail/seccomp.c
+++ b/src/firejail/seccomp.c
@@ -290,9 +290,8 @@ static void write_seccomp_file(void) {
290 fprintf(stderr, "Error: cannot save seccomp filter\n"); 290 fprintf(stderr, "Error: cannot save seccomp filter\n");
291 exit(1); 291 exit(1);
292 } 292 }
293 SET_PERMS_FD(fd, 0, 0, S_IRUSR | S_IWUSR);
293 close(fd); 294 close(fd);
294 if (chown(RUN_SECCOMP_CFG, 0, 0) < 0)
295 errExit("chown");
296} 295}
297 296
298// read seccomp filter from /run/firejail/mnt/seccomp 297// read seccomp filter from /run/firejail/mnt/seccomp
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index 3d0918b2c..a68b54cdb 100644
--- a/src/firejail/x11.c
+++ b/src/firejail/x11.c
@@ -132,13 +132,9 @@ void fs_x11(void) {
132 fprintf(stderr, "Error: cannot create empty file in x11 directory\n"); 132 fprintf(stderr, "Error: cannot create empty file in x11 directory\n");
133 exit(1); 133 exit(1);
134 } 134 }
135 fclose(fp);
136
137 // set file properties 135 // set file properties
138 if (chown(x11file, s.st_uid, s.st_gid) < 0) 136 SET_PERMS_STREAM(fp, s.st_uid, s.st_gid, s.st_mode);
139 errExit("chown"); 137 fclose(fp);
140 if (chmod(x11file, s.st_mode) < 0)
141 errExit("chmod");
142 138
143 // mount 139 // mount
144 char *wx11file; 140 char *wx11file;