aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/firejail/fs.c120
-rw-r--r--src/firejail/fs_home.c25
-rw-r--r--src/firejail/ls.c6
-rw-r--r--src/firejail/pulseaudio.c2
-rw-r--r--src/firejail/util.c7
-rw-r--r--src/include/euid_common.h6
6 files changed, 55 insertions, 111 deletions
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 6c87df1e9..21ab56bd8 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -29,16 +29,25 @@
29 29
30static void fs_rdwr(const char *dir); 30static void fs_rdwr(const char *dir);
31 31
32static void create_dir_as_root(const char *dir, mode_t mode) {
33 assert(dir);
34 if (arg_debug)
35 printf("Creating %s directory\n", dir);
36
37 if (mkdir(dir, mode) == -1)
38 errExit("mkdir");
39
40 ASSERT_PERMS(dir, 0, 0, mode);
41}
42
32static void create_empty_dir(void) { 43static void create_empty_dir(void) {
33 struct stat s; 44 struct stat s;
34 45
35 if (stat(RUN_RO_DIR, &s)) { 46 if (stat(RUN_RO_DIR, &s)) {
36 /* coverity[toctou] */ 47 /* coverity[toctou] */
37 int rv = mkdir(RUN_RO_DIR, S_IRUSR | S_IXUSR); 48 if (mkdir(RUN_RO_DIR, S_IRUSR | S_IXUSR) == -1)
38 if (rv == -1) 49 errExit("mkdir");
39 errExit("mkdir"); 50 ASSERT_PERMS(RUN_RO_DIR, 0, 0, S_IRUSR | S_IXUSR);
40 if (chown(RUN_RO_DIR, 0, 0) < 0)
41 errExit("chown");
42 } 51 }
43} 52}
44 53
@@ -50,11 +59,16 @@ static void create_empty_file(void) {
50 FILE *fp = fopen(RUN_RO_FILE, "w"); 59 FILE *fp = fopen(RUN_RO_FILE, "w");
51 if (!fp) 60 if (!fp)
52 errExit("fopen"); 61 errExit("fopen");
53 fclose(fp); 62
54 if (chown(RUN_RO_FILE, 0, 0) < 0) 63 int fd = fileno(fp);
64 if (fd == -1)
65 errExit("fileno");
66 if (fchown(fd, 0, 0) < 0)
55 errExit("chown"); 67 errExit("chown");
56 if (chmod(RUN_RO_FILE, S_IRUSR) < 0) 68 if (fchmod(fd, S_IRUSR) < 0)
57 errExit("chown"); 69 errExit("chown");
70
71 fclose(fp);
58 } 72 }
59} 73}
60 74
@@ -64,16 +78,7 @@ void fs_build_firejail_dir(void) {
64 78
65 // CentOS 6 doesn't have /run directory 79 // CentOS 6 doesn't have /run directory
66 if (stat(RUN_FIREJAIL_BASEDIR, &s)) { 80 if (stat(RUN_FIREJAIL_BASEDIR, &s)) {
67 if (arg_debug) 81 create_dir_as_root(RUN_FIREJAIL_BASEDIR, 0755);
68 printf("Creating %s directory\n", RUN_FIREJAIL_BASEDIR);
69 /* coverity[toctou] */
70 int rv = mkdir(RUN_FIREJAIL_BASEDIR, 0755);
71 if (rv == -1)
72 errExit("mkdir");
73 if (chown(RUN_FIREJAIL_BASEDIR, 0, 0) < 0)
74 errExit("chown");
75 if (chmod(RUN_FIREJAIL_BASEDIR, 0755) < 0)
76 errExit("chmod");
77 } 82 }
78 else { // check /tmp/firejail directory belongs to root end exit if doesn't! 83 else { // check /tmp/firejail directory belongs to root end exit if doesn't!
79 if (s.st_uid != 0 || s.st_gid != 0) { 84 if (s.st_uid != 0 || s.st_gid != 0) {
@@ -83,61 +88,23 @@ void fs_build_firejail_dir(void) {
83 } 88 }
84 89
85 if (stat(RUN_FIREJAIL_DIR, &s)) { 90 if (stat(RUN_FIREJAIL_DIR, &s)) {
86 if (arg_debug) 91 create_dir_as_root(RUN_FIREJAIL_DIR, 0755);
87 printf("Creating %s directory\n", RUN_FIREJAIL_DIR);
88 /* coverity[toctou] */
89 int rv = mkdir(RUN_FIREJAIL_DIR, 0755);
90 if (rv == -1)
91 errExit("mkdir");
92 if (chown(RUN_FIREJAIL_DIR, 0, 0) < 0)
93 errExit("chown");
94 if (chmod(RUN_FIREJAIL_DIR, 0755) < 0)
95 errExit("chmod");
96 } 92 }
97 93
98 if (stat(RUN_FIREJAIL_NETWORK_DIR, &s)) { 94 if (stat(RUN_FIREJAIL_NETWORK_DIR, &s)) {
99 if (arg_debug) 95 create_dir_as_root(RUN_FIREJAIL_NETWORK_DIR, 0755);
100 printf("Creating %s directory\n", RUN_FIREJAIL_NETWORK_DIR);
101
102 if (mkdir(RUN_FIREJAIL_NETWORK_DIR, 0755) == -1)
103 errExit("mkdir");
104 if (chown(RUN_FIREJAIL_NETWORK_DIR, 0, 0) < 0)
105 errExit("chown");
106 if (chmod(RUN_FIREJAIL_NETWORK_DIR, 0755) < 0)
107 errExit("chmod");
108 } 96 }
109 97
110 if (stat(RUN_FIREJAIL_BANDWIDTH_DIR, &s)) { 98 if (stat(RUN_FIREJAIL_BANDWIDTH_DIR, &s)) {
111 if (arg_debug) 99 create_dir_as_root(RUN_FIREJAIL_BANDWIDTH_DIR, 0755);
112 printf("Creating %s directory\n", RUN_FIREJAIL_BANDWIDTH_DIR);
113 if (mkdir(RUN_FIREJAIL_BANDWIDTH_DIR, 0755) == -1)
114 errExit("mkdir");
115 if (chown(RUN_FIREJAIL_BANDWIDTH_DIR, 0, 0) < 0)
116 errExit("chown");
117 if (chmod(RUN_FIREJAIL_BANDWIDTH_DIR, 0755) < 0)
118 errExit("chmod");
119 } 100 }
120 101
121 if (stat(RUN_FIREJAIL_NAME_DIR, &s)) { 102 if (stat(RUN_FIREJAIL_NAME_DIR, &s)) {
122 if (arg_debug) 103 create_dir_as_root(RUN_FIREJAIL_NAME_DIR, 0755);
123 printf("Creating %s directory\n", RUN_FIREJAIL_NAME_DIR);
124 if (mkdir(RUN_FIREJAIL_NAME_DIR, 0755) == -1)
125 errExit("mkdir");
126 if (chown(RUN_FIREJAIL_NAME_DIR, 0, 0) < 0)
127 errExit("chown");
128 if (chmod(RUN_FIREJAIL_NAME_DIR, 0755) < 0)
129 errExit("chmod");
130 } 104 }
131 105
132 if (stat(RUN_FIREJAIL_X11_DIR, &s)) { 106 if (stat(RUN_FIREJAIL_X11_DIR, &s)) {
133 if (arg_debug) 107 create_dir_as_root(RUN_FIREJAIL_X11_DIR, 0755);
134 printf("Creating %s directory\n", RUN_FIREJAIL_X11_DIR);
135 if (mkdir(RUN_FIREJAIL_X11_DIR, 0755) == -1)
136 errExit("mkdir");
137 if (chown(RUN_FIREJAIL_X11_DIR, 0, 0) < 0)
138 errExit("chown");
139 if (chmod(RUN_FIREJAIL_X11_DIR, 0755) < 0)
140 errExit("chmod");
141 } 108 }
142 109
143 create_empty_dir(); 110 create_empty_dir();
@@ -160,16 +127,7 @@ void fs_build_mnt_dir(void) {
160 127
161 // create /run/firejail/mnt directory 128 // create /run/firejail/mnt directory
162 if (stat(RUN_MNT_DIR, &s)) { 129 if (stat(RUN_MNT_DIR, &s)) {
163 if (arg_debug) 130 create_dir_as_root(RUN_MNT_DIR, 0755);
164 printf("Creating %s directory\n", RUN_MNT_DIR);
165 /* coverity[toctou] */
166 int rv = mkdir(RUN_MNT_DIR, 0755);
167 if (rv == -1)
168 errExit("mkdir");
169 if (chown(RUN_MNT_DIR, 0, 0) < 0)
170 errExit("chown");
171 if (chmod(RUN_MNT_DIR, 0755) < 0)
172 errExit("chmod");
173 } 131 }
174 132
175 // ... and mount tmpfs on top of it 133 // ... and mount tmpfs on top of it
@@ -202,16 +160,12 @@ void fs_build_cp_command(void) {
202 fprintf(stderr, "Error: invalid /bin/cp file\n"); 160 fprintf(stderr, "Error: invalid /bin/cp file\n");
203 exit(1); 161 exit(1);
204 } 162 }
205 int rv = copy_file(fname, RUN_CP_COMMAND); 163 int rv = copy_file(fname, RUN_CP_COMMAND, 0, 0, 0755);
206 if (rv) { 164 if (rv) {
207 fprintf(stderr, "Error: cannot access /bin/cp\n"); 165 fprintf(stderr, "Error: cannot access /bin/cp\n");
208 exit(1); 166 exit(1);
209 } 167 }
210 /* coverity[toctou] */ 168 ASSERT_PERMS(RUN_CP_COMMAND, 0, 0, 0755);
211 if (chown(RUN_CP_COMMAND, 0, 0))
212 errExit("chown");
213 if (chmod(RUN_CP_COMMAND, 0755))
214 errExit("chmod");
215 169
216 free(fname); 170 free(fname);
217 } 171 }
@@ -827,10 +781,7 @@ char *fs_check_overlay_dir(const char *subdirname, int allow_reuse) {
827 /* coverity[toctou] */ 781 /* coverity[toctou] */
828 if (mkdir(dirname, 0700)) 782 if (mkdir(dirname, 0700))
829 errExit("mkdir"); 783 errExit("mkdir");
830 if (chown(dirname, getuid(), getgid()) < 0) 784 ASSERT_PERMS(dirname, getuid(), getgid(), 0700);
831 errExit("chown");
832 if (chmod(dirname, 0700) < 0)
833 errExit("chmod");
834 } 785 }
835 else if (is_link(dirname)) { 786 else if (is_link(dirname)) {
836 fprintf(stderr, "Error: invalid ~/.firejail directory\n"); 787 fprintf(stderr, "Error: invalid ~/.firejail directory\n");
@@ -917,10 +868,7 @@ void fs_overlayfs(void) {
917 errExit("asprintf"); 868 errExit("asprintf");
918 if (mkdir(oroot, 0755)) 869 if (mkdir(oroot, 0755))
919 errExit("mkdir"); 870 errExit("mkdir");
920 if (chown(oroot, 0, 0) < 0) 871 ASSERT_PERMS(oroot, 0, 0, 0755);
921 errExit("chown");
922 if (chmod(oroot, 0755) < 0)
923 errExit("chmod");
924 872
925 struct stat s; 873 struct stat s;
926 char *basedir = RUN_MNT_DIR; 874 char *basedir = RUN_MNT_DIR;
@@ -1259,7 +1207,7 @@ void fs_chroot(const char *rootdir) {
1259 fprintf(stderr, "Error: invalid %s file\n", fname); 1207 fprintf(stderr, "Error: invalid %s file\n", fname);
1260 exit(1); 1208 exit(1);
1261 } 1209 }
1262 if (copy_file("/etc/resolv.conf", fname) == -1) 1210 if (copy_file("/etc/resolv.conf", fname, 0, 0, 0644) == -1)
1263 fprintf(stderr, "Warning: /etc/resolv.conf not initialized\n"); 1211 fprintf(stderr, "Warning: /etc/resolv.conf not initialized\n");
1264 } 1212 }
1265 1213
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index d328d5f1c..75d69e021 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -43,9 +43,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
43 if (stat(fname, &s) == 0) 43 if (stat(fname, &s) == 0)
44 return; 44 return;
45 if (stat("/etc/skel/.zshrc", &s) == 0) { 45 if (stat("/etc/skel/.zshrc", &s) == 0) {
46 if (copy_file("/etc/skel/.zshrc", fname) == 0) { 46 if (copy_file("/etc/skel/.zshrc", fname, u, g, 0644) == 0) {
47 if (chown(fname, u, g) == -1)
48 errExit("chown");
49 fs_logger("clone /etc/skel/.zshrc"); 47 fs_logger("clone /etc/skel/.zshrc");
50 } 48 }
51 } 49 }
@@ -73,9 +71,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
73 if (stat(fname, &s) == 0) 71 if (stat(fname, &s) == 0)
74 return; 72 return;
75 if (stat("/etc/skel/.cshrc", &s) == 0) { 73 if (stat("/etc/skel/.cshrc", &s) == 0) {
76 if (copy_file("/etc/skel/.cshrc", fname) == 0) { 74 if (copy_file("/etc/skel/.cshrc", fname, u, g, 0644) == 0) {
77 if (chown(fname, u, g) == -1)
78 errExit("chown");
79 fs_logger("clone /etc/skel/.cshrc"); 75 fs_logger("clone /etc/skel/.cshrc");
80 } 76 }
81 } 77 }
@@ -104,10 +100,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
104 if (stat(fname, &s) == 0) 100 if (stat(fname, &s) == 0)
105 return; 101 return;
106 if (stat("/etc/skel/.bashrc", &s) == 0) { 102 if (stat("/etc/skel/.bashrc", &s) == 0) {
107 if (copy_file("/etc/skel/.bashrc", fname) == 0) { 103 if (copy_file("/etc/skel/.bashrc", fname, u, g, 0644) == 0) {
108 /* coverity[toctou] */
109 if (chown(fname, u, g) == -1)
110 errExit("chown");
111 fs_logger("clone /etc/skel/.bashrc"); 104 fs_logger("clone /etc/skel/.bashrc");
112 } 105 }
113 } 106 }
@@ -131,7 +124,7 @@ static int store_xauthority(void) {
131 exit(1); 124 exit(1);
132 } 125 }
133 126
134 int rv = copy_file(src, dest); 127 int rv = copy_file(src, dest, -1, -1, 0600);
135 if (rv) { 128 if (rv) {
136 fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); 129 fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n");
137 return 0; 130 return 0;
@@ -167,7 +160,7 @@ static int store_asoundrc(void) {
167 free(rp); 160 free(rp);
168 } 161 }
169 162
170 int rv = copy_file(src, dest); 163 int rv = copy_file(src, dest, -1, -1, -0644);
171 if (rv) { 164 if (rv) {
172 fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); 165 fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n");
173 return 0; 166 return 0;
@@ -184,7 +177,7 @@ static void copy_xauthority(void) {
184 char *dest; 177 char *dest;
185 if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1) 178 if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1)
186 errExit("asprintf"); 179 errExit("asprintf");
187 int rv = copy_file(src, dest); 180 int rv = copy_file(src, dest, -1, -1, 0600);
188 if (rv) 181 if (rv)
189 fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); 182 fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n");
190 else { 183 else {
@@ -207,7 +200,7 @@ static void copy_asoundrc(void) {
207 char *dest; 200 char *dest;
208 if (asprintf(&dest, "%s/.asoundrc", cfg.homedir) == -1) 201 if (asprintf(&dest, "%s/.asoundrc", cfg.homedir) == -1)
209 errExit("asprintf"); 202 errExit("asprintf");
210 int rv = copy_file(src, dest); 203 int rv = copy_file(src, dest, -1 , -1, 0644);
211 if (rv) 204 if (rv)
212 fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); 205 fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n");
213 else { 206 else {
@@ -360,11 +353,9 @@ int fs_copydir(const char *path, const struct stat *st, int ftype, struct FTW *s
360 return(0); 353 return(0);
361 if (stat(path, &s) == 0) { 354 if (stat(path, &s) == 0) {
362 if(ftype == FTW_F) { 355 if(ftype == FTW_F) {
363 if (copy_file(path, dest) == 0) { 356 if (copy_file(path, dest, u, g, 0644) == 0) {
364 if (arg_debug) 357 if (arg_debug)
365 printf("copy from %s to %s\n", path, dest); 358 printf("copy from %s to %s\n", path, dest);
366 if (chown(dest, u, g) == -1)
367 errExit("chown");
368 fs_logger2("clone", path); 359 fs_logger2("clone", path);
369 } 360 }
370 } 361 }
diff --git a/src/firejail/ls.c b/src/firejail/ls.c
index 09577fb0c..495aaf8e2 100644
--- a/src/firejail/ls.c
+++ b/src/firejail/ls.c
@@ -374,11 +374,7 @@ void sandboxfs(int op, pid_t pid, const char *path) {
374 } 374 }
375 // copy file 375 // copy file
376 EUID_ROOT(); 376 EUID_ROOT();
377 copy_file(src_fname, dest_fname); 377 copy_file(src_fname, dest_fname, getuid(), getgid(), 0644);
378 if (chown(dest_fname, getuid(), getgid()) == -1)
379 errExit("chown");
380 if (chmod(dest_fname, 0644) == -1)
381 errExit("chmod");
382 printf("Transfer complete\n"); 378 printf("Transfer complete\n");
383 EUID_USER(); 379 EUID_USER();
384 } 380 }
diff --git a/src/firejail/pulseaudio.c b/src/firejail/pulseaudio.c
index 908ef1d25..dd26d219c 100644
--- a/src/firejail/pulseaudio.c
+++ b/src/firejail/pulseaudio.c
@@ -114,7 +114,7 @@ void pulseaudio_init(void) {
114 char *pulsecfg = NULL; 114 char *pulsecfg = NULL;
115 if (asprintf(&pulsecfg, "%s/client.conf", RUN_PULSE_DIR) == -1) 115 if (asprintf(&pulsecfg, "%s/client.conf", RUN_PULSE_DIR) == -1)
116 errExit("asprintf"); 116 errExit("asprintf");
117 if (copy_file("/etc/pulse/client.conf", pulsecfg)) 117 if (copy_file("/etc/pulse/client.conf", pulsecfg, -1, -1, 0644))
118 errExit("copy_file"); 118 errExit("copy_file");
119 FILE *fp = fopen(pulsecfg, "a+"); 119 FILE *fp = fopen(pulsecfg, "a+");
120 if (!fp) 120 if (!fp)
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 24bb71e4c..22434e200 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -170,7 +170,7 @@ void logerr(const char *msg) {
170 170
171 171
172// return -1 if error, 0 if no error 172// return -1 if error, 0 if no error
173int copy_file(const char *srcname, const char *destname) { 173int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode) {
174 assert(srcname); 174 assert(srcname);
175 assert(destname); 175 assert(destname);
176 176
@@ -207,6 +207,11 @@ int copy_file(const char *srcname, const char *destname) {
207 } 207 }
208 } 208 }
209 209
210 if (fchown(dst, uid, gid) == -1)
211 errExit("fchown");
212 if (fchmod(dst, mode) == -1)
213 errExit("fchmod");
214
210 close(src); 215 close(src);
211 close(dst); 216 close(dst);
212 return 0; 217 return 0;
diff --git a/src/include/euid_common.h b/src/include/euid_common.h
index b6d341bf4..de5572fb1 100644
--- a/src/include/euid_common.h
+++ b/src/include/euid_common.h
@@ -37,11 +37,15 @@ extern uid_t firejail_uid;
37static inline void EUID_ROOT(void) { 37static inline void EUID_ROOT(void) {
38 if (seteuid(0) == -1) 38 if (seteuid(0) == -1)
39 fprintf(stderr, "Warning: cannot switch euid to root\n"); 39 fprintf(stderr, "Warning: cannot switch euid to root\n");
40 if (setegid(0) == -1)
41 fprintf(stderr, "Warning: cannot switch egid to root\n");
40} 42}
41 43
42static inline void EUID_USER(void) { 44static inline void EUID_USER(void) {
43 if (seteuid(firejail_uid) == -1) 45 if (seteuid(firejail_uid) == -1)
44 fprintf(stderr, "Warning: cannot switch euid to user\n"); 46 errExit("seteuid");
47 if (setegid(firejail_uid) == -1)
48 errExit("setegid");
45} 49}
46 50
47static inline void EUID_PRINT(void) { 51static inline void EUID_PRINT(void) {