aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--RELNOTES1
-rw-r--r--src/firejail/firejail.h9
-rw-r--r--src/firejail/fs.c24
-rw-r--r--src/firejail/fs_bin.c6
-rw-r--r--src/firejail/fs_dev.c15
-rw-r--r--src/firejail/fs_etc.c6
-rw-r--r--src/firejail/fs_home.c21
-rw-r--r--src/firejail/fs_hostname.c5
-rw-r--r--src/firejail/fs_trace.c2
-rw-r--r--src/firejail/fs_var.c19
-rw-r--r--src/firejail/fs_whitelist.c12
-rw-r--r--src/firejail/main.c10
-rw-r--r--src/firejail/pulseaudio.c1
-rw-r--r--src/firejail/restrict_users.c39
-rw-r--r--src/firejail/sandbox.c5
-rw-r--r--src/firejail/usage.c6
-rw-r--r--src/firejail/util.c6
-rw-r--r--src/man/firejail.txt29
-rw-r--r--todo8
19 files changed, 181 insertions, 43 deletions
diff --git a/RELNOTES b/RELNOTES
index 1b2c28726..fd004fb0e 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -10,6 +10,7 @@ firejail (0.9.35) baseline; urgency=low
10 * added automated feature testing framework 10 * added automated feature testing framework
11 * alow default gateway configuration for --interface option 11 * alow default gateway configuration for --interface option
12 * --debug enhancements 12 * --debug enhancements
13 * filesystem log
13 * bugfixes 14 * bugfixes
14 -- netblue30 <netblue30@yahoo.com> ongoing development 15 -- netblue30 <netblue30@yahoo.com> ongoing development
15 16
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index e4e6f4fa4..b50b4d19e 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -56,6 +56,7 @@
56#define RUN_UTMP_FILE "/run/firejail/mnt/utmp" 56#define RUN_UTMP_FILE "/run/firejail/mnt/utmp"
57#define RUN_PASSWD_FILE "/run/firejail/mnt/passwd" 57#define RUN_PASSWD_FILE "/run/firejail/mnt/passwd"
58#define RUN_GROUP_FILE "/run/firejail/mnt/group" 58#define RUN_GROUP_FILE "/run/firejail/mnt/group"
59#define RUN_FSLOGGER_FILE "/run/firejail/mnt/fslogger"
59 60
60// profiles 61// profiles
61#define DEFAULT_USER_PROFILE "generic" 62#define DEFAULT_USER_PROFILE "generic"
@@ -479,6 +480,14 @@ void protocol_filter_load(const char *fname);
479// restrict_users.c 480// restrict_users.c
480void restrict_users(void); 481void restrict_users(void);
481 482
483// fs_logger.c
484void fs_logger(const char *msg);
485void fs_logger2(const char *msg1, const char *msg2);
486void fs_logger3(const char *msg1, const char *msg2, const char *msg3);
487void fs_logger_print(void);
488void fs_logger_change_owner(void);
489void fs_logger_print_log_name(const char *name);
490void fs_logger_print_log(pid_t pid);
482 491
483#endif 492#endif
484 493
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index e442bc705..6572f657b 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -213,6 +213,7 @@ static void disable_file(OPERATION op, const char *filename) {
213 errExit("disable file"); 213 errExit("disable file");
214 } 214 }
215 last_disable = SUCCESSFUL; 215 last_disable = SUCCESSFUL;
216 fs_logger2("blacklist", fname);
216 } 217 }
217 } 218 }
218 else if (op == MOUNT_READONLY) { 219 else if (op == MOUNT_READONLY) {
@@ -232,6 +233,7 @@ static void disable_file(OPERATION op, const char *filename) {
232 if (chown(fname, s.st_uid, s.st_gid) == -1) 233 if (chown(fname, s.st_uid, s.st_gid) == -1)
233 errExit("mounting tmpfs chmod"); 234 errExit("mounting tmpfs chmod");
234 last_disable = SUCCESSFUL; 235 last_disable = SUCCESSFUL;
236 fs_logger2("mount tmpfs on", fname);
235 } 237 }
236 else 238 else
237 printf("Warning: %s is not a directory; cannot mount a tmpfs on top of it.\n", fname); 239 printf("Warning: %s is not a directory; cannot mount a tmpfs on top of it.\n", fname);
@@ -427,6 +429,7 @@ void fs_rdonly(const char *dir) {
427 // mount --bind -o remount,ro /bin 429 // mount --bind -o remount,ro /bin
428 if (mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL) < 0) 430 if (mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL) < 0)
429 errExit("mount read-only"); 431 errExit("mount read-only");
432 fs_logger2("read-only", dir);
430 } 433 }
431} 434}
432void fs_rdonly_noexit(const char *dir) { 435void fs_rdonly_noexit(const char *dir) {
@@ -444,6 +447,8 @@ void fs_rdonly_noexit(const char *dir) {
444 merr = 1; 447 merr = 1;
445 if (merr) 448 if (merr)
446 fprintf(stderr, "Warning: cannot mount %s read-only\n", dir); 449 fprintf(stderr, "Warning: cannot mount %s read-only\n", dir);
450 else
451 fs_logger2("read-only", dir);
447 } 452 }
448} 453}
449 454
@@ -455,6 +460,7 @@ void fs_proc_sys_dev_boot(void) {
455 printf("Remounting /proc and /proc/sys filesystems\n"); 460 printf("Remounting /proc and /proc/sys filesystems\n");
456 if (mount("proc", "/proc", "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_REC, NULL) < 0) 461 if (mount("proc", "/proc", "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_REC, NULL) < 0)
457 errExit("mounting /proc"); 462 errExit("mounting /proc");
463 fs_logger("remount /proc");
458 464
459 // remount /proc/sys readonly 465 // remount /proc/sys readonly
460 if (mount("/proc/sys", "/proc/sys", NULL, MS_BIND | MS_REC, NULL) < 0) 466 if (mount("/proc/sys", "/proc/sys", NULL, MS_BIND | MS_REC, NULL) < 0)
@@ -462,6 +468,7 @@ void fs_proc_sys_dev_boot(void) {
462 468
463 if (mount(NULL, "/proc/sys", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY | MS_REC, NULL) < 0) 469 if (mount(NULL, "/proc/sys", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY | MS_REC, NULL) < 0)
464 errExit("mounting /proc/sys"); 470 errExit("mounting /proc/sys");
471 fs_logger("read-only /proc/sys");
465 472
466 473
467 /* Mount a version of /sys that describes the network namespace */ 474 /* Mount a version of /sys that describes the network namespace */
@@ -471,28 +478,45 @@ void fs_proc_sys_dev_boot(void) {
471 fprintf(stderr, "Warning: failed to unmount /sys\n"); 478 fprintf(stderr, "Warning: failed to unmount /sys\n");
472 if (mount("sysfs", "/sys", "sysfs", MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REC, NULL) < 0) 479 if (mount("sysfs", "/sys", "sysfs", MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REC, NULL) < 0)
473 fprintf(stderr, "Warning: failed to mount /sys\n"); 480 fprintf(stderr, "Warning: failed to mount /sys\n");
481 else
482 fs_logger("remount /sys");
483
474 484
475 485
476 if (arg_debug) 486 if (arg_debug)
477 printf("Disable /sys/firmware directory\n"); 487 printf("Disable /sys/firmware directory\n");
478 if (mount("tmpfs", "/sys/firmware", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 488 if (mount("tmpfs", "/sys/firmware", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
479 fprintf(stderr, "Warning: cannot disable /sys/firmware directory\n"); 489 fprintf(stderr, "Warning: cannot disable /sys/firmware directory\n");
490 else
491 fs_logger("mount tmpfs on /sys/firmware");
492
480 if (arg_debug) 493 if (arg_debug)
481 printf("Disable /sys/hypervisor directory\n"); 494 printf("Disable /sys/hypervisor directory\n");
482 if (mount("tmpfs", "/sys/hypervisor", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 495 if (mount("tmpfs", "/sys/hypervisor", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
483 fprintf(stderr, "Warning: cannot disable /sys/hypervisor directory\n"); 496 fprintf(stderr, "Warning: cannot disable /sys/hypervisor directory\n");
497 else
498 fs_logger("mount tmpfs on /sys/hypervisor");
499
484 if (arg_debug) 500 if (arg_debug)
485 printf("Disable /sys/fs directory\n"); 501 printf("Disable /sys/fs directory\n");
486 if (mount("tmpfs", "/sys/fs", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 502 if (mount("tmpfs", "/sys/fs", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
487 fprintf(stderr, "Warning: cannot disable /sys/fs directory\n"); 503 fprintf(stderr, "Warning: cannot disable /sys/fs directory\n");
504 else
505 fs_logger("mount tmpfs on /sys/fs");
506
488 if (arg_debug) 507 if (arg_debug)
489 printf("Disable /sys/module directory\n"); 508 printf("Disable /sys/module directory\n");
490 if (mount("tmpfs", "/sys/module", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 509 if (mount("tmpfs", "/sys/module", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
491 fprintf(stderr, "Warning: cannot disable /sys/module directory\n"); 510 fprintf(stderr, "Warning: cannot disable /sys/module directory\n");
511 else
512 fs_logger("mount tmpfs on /sys/module");
513
492 if (arg_debug) 514 if (arg_debug)
493 printf("Disable /sys/power directory\n"); 515 printf("Disable /sys/power directory\n");
494 if (mount("tmpfs", "/sys/power", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 516 if (mount("tmpfs", "/sys/power", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
495 fprintf(stderr, "Warning: cannot disable /sys/power directory\n"); 517 fprintf(stderr, "Warning: cannot disable /sys/power directory\n");
518 else
519 fs_logger("mount tmpfs on /sys/power");
496 520
497 521
498 522
diff --git a/src/firejail/fs_bin.c b/src/firejail/fs_bin.c
index 946c75d30..a990d9d79 100644
--- a/src/firejail/fs_bin.c
+++ b/src/firejail/fs_bin.c
@@ -143,6 +143,7 @@ static void duplicate(char *fname) {
143 printf("%s\n", cmd); 143 printf("%s\n", cmd);
144 if (system(cmd)) 144 if (system(cmd))
145 errExit("system cp -a"); 145 errExit("system cp -a");
146 fs_logger2("clone", fname);
146 free(cmd); 147 free(cmd);
147 free(actual_path); 148 free(actual_path);
148 } 149 }
@@ -176,8 +177,10 @@ void fs_private_bin_list(void) {
176 if (chmod(RUN_BIN_DIR, 0755) < 0) 177 if (chmod(RUN_BIN_DIR, 0755) < 0)
177 errExit("chmod"); 178 errExit("chmod");
178 179
180
179 // copy the list of files in the new etc directory 181 // copy the list of files in the new etc directory
180 // using a new child process without root privileges 182 // using a new child process without root privileges
183 fs_logger_print(); // save the current log
181 pid_t child = fork(); 184 pid_t child = fork();
182 if (child < 0) 185 if (child < 0)
183 errExit("fork"); 186 errExit("fork");
@@ -196,12 +199,14 @@ void fs_private_bin_list(void) {
196 if (!dlist) 199 if (!dlist)
197 errExit("strdup"); 200 errExit("strdup");
198 201
202
199 char *ptr = strtok(dlist, ","); 203 char *ptr = strtok(dlist, ",");
200 duplicate(ptr); 204 duplicate(ptr);
201 205
202 while ((ptr = strtok(NULL, ",")) != NULL) 206 while ((ptr = strtok(NULL, ",")) != NULL)
203 duplicate(ptr); 207 duplicate(ptr);
204 free(dlist); 208 free(dlist);
209 fs_logger_print();
205 exit(0); 210 exit(0);
206 } 211 }
207 // wait for the child to finish 212 // wait for the child to finish
@@ -214,6 +219,7 @@ void fs_private_bin_list(void) {
214 printf("Mount-bind %s on top of %s\n", RUN_BIN_DIR, paths[i]); 219 printf("Mount-bind %s on top of %s\n", RUN_BIN_DIR, paths[i]);
215 if (mount(RUN_BIN_DIR, paths[i], NULL, MS_BIND|MS_REC, NULL) < 0) 220 if (mount(RUN_BIN_DIR, paths[i], NULL, MS_BIND|MS_REC, NULL) < 0)
216 errExit("mount bind"); 221 errExit("mount bind");
222 fs_logger2("mount", paths[i]);
217 i++; 223 i++;
218 } 224 }
219} 225}
diff --git a/src/firejail/fs_dev.c b/src/firejail/fs_dev.c
index 86e0918e1..c0cb49db7 100644
--- a/src/firejail/fs_dev.c
+++ b/src/firejail/fs_dev.c
@@ -107,6 +107,7 @@ void fs_private_dev(void){
107 // mount tmpfs on top of /dev 107 // mount tmpfs on top of /dev
108 if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) 108 if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0)
109 errExit("mounting /dev"); 109 errExit("mounting /dev");
110 fs_logger("mount tmpfs on /dev");
110 111
111 // bring back /dev/log 112 // bring back /dev/log
112 if (have_devlog) { 113 if (have_devlog) {
@@ -116,6 +117,7 @@ void fs_private_dev(void){
116 fclose(fp); 117 fclose(fp);
117 if (mount(RUN_DEVLOG_FILE, "/dev/log", NULL, MS_BIND|MS_REC, NULL) < 0) 118 if (mount(RUN_DEVLOG_FILE, "/dev/log", NULL, MS_BIND|MS_REC, NULL) < 0)
118 errExit("mounting /dev/log"); 119 errExit("mounting /dev/log");
120 fs_logger("clone /dev/log");
119 } 121 }
120 } 122 }
121 123
@@ -131,6 +133,7 @@ void fs_private_dev(void){
131 errExit("chmod"); 133 errExit("chmod");
132 if (mount(RUN_DRI_DIR, "/dev/dri", NULL, MS_BIND|MS_REC, NULL) < 0) 134 if (mount(RUN_DRI_DIR, "/dev/dri", NULL, MS_BIND|MS_REC, NULL) < 0)
133 errExit("mounting /dev/dri"); 135 errExit("mounting /dev/dri");
136 fs_logger("clone /dev/dri");
134 } 137 }
135 138
136 // create /dev/shm 139 // create /dev/shm
@@ -143,14 +146,21 @@ void fs_private_dev(void){
143 errExit("chown"); 146 errExit("chown");
144 if (chmod("/dev/shm", 0777) < 0) 147 if (chmod("/dev/shm", 0777) < 0)
145 errExit("chmod"); 148 errExit("chmod");
149 fs_logger("mkdir /dev/shm");
146 150
147 // create devices 151 // create devices
148 create_char_dev("/dev/zero", 0666, 1, 5); // mknod -m 666 /dev/zero c 1 5 152 create_char_dev("/dev/zero", 0666, 1, 5); // mknod -m 666 /dev/zero c 1 5
153 fs_logger("mknod /dev/zero");
149 create_char_dev("/dev/null", 0666, 1, 3); // mknod -m 666 /dev/null c 1 3 154 create_char_dev("/dev/null", 0666, 1, 3); // mknod -m 666 /dev/null c 1 3
155 fs_logger("mknod /dev/null");
150 create_char_dev("/dev/full", 0666, 1, 7); // mknod -m 666 /dev/full c 1 7 156 create_char_dev("/dev/full", 0666, 1, 7); // mknod -m 666 /dev/full c 1 7
157 fs_logger("mknod /dev/full");
151 create_char_dev("/dev/random", 0666, 1, 8); // Mknod -m 666 /dev/random c 1 8 158 create_char_dev("/dev/random", 0666, 1, 8); // Mknod -m 666 /dev/random c 1 8
159 fs_logger("mknod /dev/random");
152 create_char_dev("/dev/urandom", 0666, 1, 9); // mknod -m 666 /dev/urandom c 1 9 160 create_char_dev("/dev/urandom", 0666, 1, 9); // mknod -m 666 /dev/urandom c 1 9
161 fs_logger("mknod /dev/urandom");
153 create_char_dev("/dev/tty", 0666, 5, 0); // mknod -m 666 /dev/tty c 5 0 162 create_char_dev("/dev/tty", 0666, 5, 0); // mknod -m 666 /dev/tty c 5 0
163 fs_logger("mknod /dev/tty");
154#if 0 164#if 0
155 create_dev("/dev/tty0", "mknod -m 666 /dev/tty0 c 4 0"); 165 create_dev("/dev/tty0", "mknod -m 666 /dev/tty0 c 4 0");
156 create_dev("/dev/console", "mknod -m 622 /dev/console c 5 1"); 166 create_dev("/dev/console", "mknod -m 622 /dev/console c 5 1");
@@ -164,11 +174,14 @@ void fs_private_dev(void){
164 errExit("chown"); 174 errExit("chown");
165 if (chmod("/dev/pts", 0755) < 0) 175 if (chmod("/dev/pts", 0755) < 0)
166 errExit("chmod"); 176 errExit("chmod");
177 fs_logger("mkdir /dev/pts");
167 create_char_dev("/dev/pts/ptmx", 0666, 5, 2); //"mknod -m 666 /dev/pts/ptmx c 5 2"); 178 create_char_dev("/dev/pts/ptmx", 0666, 5, 2); //"mknod -m 666 /dev/pts/ptmx c 5 2");
179 fs_logger("mknod /dev/pts/ptmx");
168 create_link("/dev/pts/ptmx", "/dev/ptmx"); 180 create_link("/dev/pts/ptmx", "/dev/ptmx");
169 // mount -vt devpts -o newinstance -o ptmxmode=0666 devpts //dev/pts 181 // mount -vt devpts -o newinstance -o ptmxmode=0666 devpts //dev/pts
170 if (mount("devpts", "/dev/pts", "devpts", MS_MGC_VAL, "newinstance,ptmxmode=0666") < 0) 182 if (mount("devpts", "/dev/pts", "devpts", MS_MGC_VAL, "newinstance,ptmxmode=0666") < 0)
171 errExit("mounting /dev/pts"); 183 errExit("mounting /dev/pts");
184 fs_logger("mount devpts");
172 185
173#if 0 186#if 0
174 // stdin, stdout, stderr 187 // stdin, stdout, stderr
@@ -190,6 +203,7 @@ void fs_dev_shm(void) {
190 printf("Mounting tmpfs on /dev/shm\n"); 203 printf("Mounting tmpfs on /dev/shm\n");
191 if (mount("tmpfs", "/dev/shm", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) 204 if (mount("tmpfs", "/dev/shm", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0)
192 errExit("mounting /dev/shm"); 205 errExit("mounting /dev/shm");
206 fs_logger("mount tmpfs on /dev/shm");
193 } 207 }
194 else { 208 else {
195 char *lnk = realpath("/dev/shm", NULL); 209 char *lnk = realpath("/dev/shm", NULL);
@@ -207,6 +221,7 @@ void fs_dev_shm(void) {
207 printf("Mounting tmpfs on %s on behalf of /dev/shm\n", lnk); 221 printf("Mounting tmpfs on %s on behalf of /dev/shm\n", lnk);
208 if (mount("tmpfs", lnk, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) 222 if (mount("tmpfs", lnk, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0)
209 errExit("mounting /var/tmp"); 223 errExit("mounting /var/tmp");
224 fs_logger3("mount tmpfs on", lnk, "on behalf of /dev/shm");
210 free(lnk); 225 free(lnk);
211 } 226 }
212 else { 227 else {
diff --git a/src/firejail/fs_etc.c b/src/firejail/fs_etc.c
index 28e337abc..df0e92203 100644
--- a/src/firejail/fs_etc.c
+++ b/src/firejail/fs_etc.c
@@ -83,6 +83,7 @@ static void duplicate(char *fname) {
83 if (system(cmd)) 83 if (system(cmd))
84 errExit("system cp -a --parents"); 84 errExit("system cp -a --parents");
85 free(cmd); 85 free(cmd);
86 fs_logger2("clone", fname);
86} 87}
87 88
88 89
@@ -108,6 +109,7 @@ void fs_private_etc_list(void) {
108 109
109 // copy the list of files in the new etc directory 110 // copy the list of files in the new etc directory
110 // using a new child process without root privileges 111 // using a new child process without root privileges
112 fs_logger_print(); // save the current log
111 pid_t child = fork(); 113 pid_t child = fork();
112 if (child < 0) 114 if (child < 0)
113 errExit("fork"); 115 errExit("fork");
@@ -126,12 +128,14 @@ void fs_private_etc_list(void) {
126 if (!dlist) 128 if (!dlist)
127 errExit("strdup"); 129 errExit("strdup");
128 130
131
129 char *ptr = strtok(dlist, ","); 132 char *ptr = strtok(dlist, ",");
130 duplicate(ptr); 133 duplicate(ptr);
131 134
132 while ((ptr = strtok(NULL, ",")) != NULL) 135 while ((ptr = strtok(NULL, ",")) != NULL)
133 duplicate(ptr); 136 duplicate(ptr);
134 free(dlist); 137 free(dlist);
138 fs_logger_print();
135 exit(0); 139 exit(0);
136 } 140 }
137 // wait for the child to finish 141 // wait for the child to finish
@@ -141,6 +145,6 @@ void fs_private_etc_list(void) {
141 printf("Mount-bind %s on top of /etc\n", RUN_ETC_DIR); 145 printf("Mount-bind %s on top of /etc\n", RUN_ETC_DIR);
142 if (mount(RUN_ETC_DIR, "/etc", NULL, MS_BIND|MS_REC, NULL) < 0) 146 if (mount(RUN_ETC_DIR, "/etc", NULL, MS_BIND|MS_REC, NULL) < 0)
143 errExit("mount bind"); 147 errExit("mount bind");
144 148 fs_logger("mount /etc");
145} 149}
146 150
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index ca9f7b472..f9e8d62f9 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -44,6 +44,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
44 if (copy_file("/etc/skel/.zshrc", fname) == 0) { 44 if (copy_file("/etc/skel/.zshrc", fname) == 0) {
45 if (chown(fname, u, g) == -1) 45 if (chown(fname, u, g) == -1)
46 errExit("chown"); 46 errExit("chown");
47 fs_logger("clone /etc/skel/.zshrc");
47 } 48 }
48 } 49 }
49 else { // 50 else { //
@@ -55,6 +56,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
55 errExit("chown"); 56 errExit("chown");
56 if (chmod(fname, S_IRUSR | S_IWUSR) < 0) 57 if (chmod(fname, S_IRUSR | S_IWUSR) < 0)
57 errExit("chown"); 58 errExit("chown");
59 fs_logger2("touch", fname);
58 } 60 }
59 } 61 }
60 free(fname); 62 free(fname);
@@ -72,6 +74,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
72 if (copy_file("/etc/skel/.cshrc", fname) == 0) { 74 if (copy_file("/etc/skel/.cshrc", fname) == 0) {
73 if (chown(fname, u, g) == -1) 75 if (chown(fname, u, g) == -1)
74 errExit("chown"); 76 errExit("chown");
77 fs_logger("clone /etc/skel/.cshrc");
75 } 78 }
76 } 79 }
77 else { // 80 else { //
@@ -84,6 +87,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
84 errExit("chown"); 87 errExit("chown");
85 if (chmod(fname, S_IRUSR | S_IWUSR) < 0) 88 if (chmod(fname, S_IRUSR | S_IWUSR) < 0)
86 errExit("chown"); 89 errExit("chown");
90 fs_logger2("touch", fname);
87 } 91 }
88 } 92 }
89 free(fname); 93 free(fname);
@@ -102,6 +106,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
102 /* coverity[toctou] */ 106 /* coverity[toctou] */
103 if (chown(fname, u, g) == -1) 107 if (chown(fname, u, g) == -1)
104 errExit("chown"); 108 errExit("chown");
109 fs_logger("clone /etc/skel/.bashrc");
105 } 110 }
106 } 111 }
107 free(fname); 112 free(fname);
@@ -139,6 +144,7 @@ static void copy_xauthority(void) {
139 int rv = copy_file(src, dest); 144 int rv = copy_file(src, dest);
140 if (rv) 145 if (rv)
141 fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); 146 fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n");
147 fs_logger2("clone", dest);
142 148
143 // set permissions and ownership 149 // set permissions and ownership
144 if (chown(dest, getuid(), getgid()) < 0) 150 if (chown(dest, getuid(), getgid()) < 0)
@@ -177,6 +183,7 @@ void fs_private_homedir(void) {
177 printf("Mount-bind %s on top of %s\n", private_homedir, homedir); 183 printf("Mount-bind %s on top of %s\n", private_homedir, homedir);
178 if (mount(private_homedir, homedir, NULL, MS_BIND|MS_REC, NULL) < 0) 184 if (mount(private_homedir, homedir, NULL, MS_BIND|MS_REC, NULL) < 0)
179 errExit("mount bind"); 185 errExit("mount bind");
186 fs_logger3("mount-bind", private_homedir, cfg.homedir);
180// preserve mode and ownership 187// preserve mode and ownership
181// if (chown(homedir, s.st_uid, s.st_gid) == -1) 188// if (chown(homedir, s.st_uid, s.st_gid) == -1)
182// errExit("mount-bind chown"); 189// errExit("mount-bind chown");
@@ -189,6 +196,7 @@ void fs_private_homedir(void) {
189 printf("Mounting a new /root directory\n"); 196 printf("Mounting a new /root directory\n");
190 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0) 197 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0)
191 errExit("mounting home directory"); 198 errExit("mounting home directory");
199 fs_logger("mount tmpfs on /root");
192 } 200 }
193 else { 201 else {
194 // mask /home 202 // mask /home
@@ -196,6 +204,7 @@ void fs_private_homedir(void) {
196 printf("Mounting a new /home directory\n"); 204 printf("Mounting a new /home directory\n");
197 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 205 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
198 errExit("mounting home directory"); 206 errExit("mounting home directory");
207 fs_logger("mount tmpfs on /home");
199 } 208 }
200 209
201 210
@@ -222,12 +231,14 @@ void fs_private(void) {
222 printf("Mounting a new /home directory\n"); 231 printf("Mounting a new /home directory\n");
223 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 232 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
224 errExit("mounting home directory"); 233 errExit("mounting home directory");
234 fs_logger("mount tmpfs on /home");
225 235
226 // mask /root 236 // mask /root
227 if (arg_debug) 237 if (arg_debug)
228 printf("Mounting a new /root directory\n"); 238 printf("Mounting a new /root directory\n");
229 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0) 239 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0)
230 errExit("mounting home directory"); 240 errExit("mounting home directory");
241 fs_logger("mount tmpfs on /root");
231 242
232 if (u != 0) { 243 if (u != 0) {
233 // create /home/user 244 // create /home/user
@@ -241,6 +252,7 @@ void fs_private(void) {
241 } 252 }
242 if (chown(homedir, u, g) < 0) 253 if (chown(homedir, u, g) < 0)
243 errExit("chown"); 254 errExit("chown");
255 fs_logger2("mkdir", homedir);
244 } 256 }
245 257
246 skel(homedir, u, g); 258 skel(homedir, u, g);
@@ -379,6 +391,7 @@ static void duplicate(char *name) {
379 printf("%s\n", cmd); 391 printf("%s\n", cmd);
380 if (system(cmd)) 392 if (system(cmd))
381 errExit("system cp -a --parents"); 393 errExit("system cp -a --parents");
394 fs_logger2("clone", fname);
382 free(cmd); 395 free(cmd);
383 free(fname); 396 free(fname);
384} 397}
@@ -415,9 +428,11 @@ void fs_private_home_list(void) {
415 errExit("chown"); 428 errExit("chown");
416 if (chmod(RUN_HOME_DIR, 0755) < 0) 429 if (chmod(RUN_HOME_DIR, 0755) < 0)
417 errExit("chmod"); 430 errExit("chmod");
431
418 432
419 // copy the list of files in the new home directory 433 // copy the list of files in the new home directory
420 // using a new child process without root privileges 434 // using a new child process without root privileges
435 fs_logger_print(); // save the current log
421 pid_t child = fork(); 436 pid_t child = fork();
422 if (child < 0) 437 if (child < 0)
423 errExit("fork"); 438 errExit("fork");
@@ -437,13 +452,14 @@ void fs_private_home_list(void) {
437 char *dlist = strdup(cfg.home_private_keep); 452 char *dlist = strdup(cfg.home_private_keep);
438 if (!dlist) 453 if (!dlist)
439 errExit("strdup"); 454 errExit("strdup");
440 455
441 char *ptr = strtok(dlist, ","); 456 char *ptr = strtok(dlist, ",");
442 duplicate(ptr); 457 duplicate(ptr);
443 458
444 while ((ptr = strtok(NULL, ",")) != NULL) 459 while ((ptr = strtok(NULL, ",")) != NULL)
445 duplicate(ptr); 460 duplicate(ptr);
446 free(dlist); 461 free(dlist);
462 fs_logger_print();
447 exit(0); 463 exit(0);
448 } 464 }
449 // wait for the child to finish 465 // wait for the child to finish
@@ -458,6 +474,7 @@ void fs_private_home_list(void) {
458 printf("Mount-bind %s on top of %s\n", newhome, homedir); 474 printf("Mount-bind %s on top of %s\n", newhome, homedir);
459 if (mount(newhome, homedir, NULL, MS_BIND|MS_REC, NULL) < 0) 475 if (mount(newhome, homedir, NULL, MS_BIND|MS_REC, NULL) < 0)
460 errExit("mount bind"); 476 errExit("mount bind");
477 fs_logger2("mount", homedir);
461// preserve mode and ownership 478// preserve mode and ownership
462// if (chown(homedir, s.st_uid, s.st_gid) == -1) 479// if (chown(homedir, s.st_uid, s.st_gid) == -1)
463// errExit("mount-bind chown"); 480// errExit("mount-bind chown");
@@ -470,6 +487,7 @@ void fs_private_home_list(void) {
470 printf("Mounting a new /root directory\n"); 487 printf("Mounting a new /root directory\n");
471 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0) 488 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0)
472 errExit("mounting home directory"); 489 errExit("mounting home directory");
490 fs_logger("mount tmpfs on /root");
473 } 491 }
474 else { 492 else {
475 // mask /home 493 // mask /home
@@ -477,6 +495,7 @@ void fs_private_home_list(void) {
477 printf("Mounting a new /home directory\n"); 495 printf("Mounting a new /home directory\n");
478 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 496 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
479 errExit("mounting home directory"); 497 errExit("mounting home directory");
498 fs_logger("mount tmpfs on /home");
480 } 499 }
481 500
482 skel(homedir, u, g); 501 skel(homedir, u, g);
diff --git a/src/firejail/fs_hostname.c b/src/firejail/fs_hostname.c
index eb3861d1b..860d0cc14 100644
--- a/src/firejail/fs_hostname.c
+++ b/src/firejail/fs_hostname.c
@@ -51,6 +51,7 @@ void fs_hostname(const char *hostname) {
51 // bind-mount the file on top of /etc/hostname 51 // bind-mount the file on top of /etc/hostname
52 if (mount(RUN_HOSTNAME_FILE, "/etc/hostname", NULL, MS_BIND|MS_REC, NULL) < 0) 52 if (mount(RUN_HOSTNAME_FILE, "/etc/hostname", NULL, MS_BIND|MS_REC, NULL) < 0)
53 errExit("mount bind /etc/hostname"); 53 errExit("mount bind /etc/hostname");
54 fs_logger("create /etc/hostname");
54 } 55 }
55 56
56 // create a new /etc/hosts 57 // create a new /etc/hosts
@@ -98,13 +99,14 @@ void fs_hostname(const char *hostname) {
98 // bind-mount the file on top of /etc/hostname 99 // bind-mount the file on top of /etc/hostname
99 if (mount(RUN_HOSTS_FILE, "/etc/hosts", NULL, MS_BIND|MS_REC, NULL) < 0) 100 if (mount(RUN_HOSTS_FILE, "/etc/hosts", NULL, MS_BIND|MS_REC, NULL) < 0)
100 errExit("mount bind /etc/hosts"); 101 errExit("mount bind /etc/hosts");
102 fs_logger("create /etc/hosts");
101 } 103 }
102} 104}
103 105
104void fs_resolvconf(void) { 106void fs_resolvconf(void) {
105 if (cfg.dns1 == 0) 107 if (cfg.dns1 == 0)
106 return; 108 return;
107 109
108 struct stat s; 110 struct stat s;
109 fs_build_mnt_dir(); 111 fs_build_mnt_dir();
110 112
@@ -135,6 +137,7 @@ void fs_resolvconf(void) {
135 // bind-mount the file on top of /etc/hostname 137 // bind-mount the file on top of /etc/hostname
136 if (mount(RUN_RESOLVCONF_FILE, "/etc/resolv.conf", NULL, MS_BIND|MS_REC, NULL) < 0) 138 if (mount(RUN_RESOLVCONF_FILE, "/etc/resolv.conf", NULL, MS_BIND|MS_REC, NULL) < 0)
137 errExit("mount bind /etc/resolv.conf"); 139 errExit("mount bind /etc/resolv.conf");
140 fs_logger("create /etc/resolv.conf");
138 } 141 }
139 else { 142 else {
140 fprintf(stderr, "Error: cannot set DNS servers, /etc/resolv.conf file is missing\n"); 143 fprintf(stderr, "Error: cannot set DNS servers, /etc/resolv.conf file is missing\n");
diff --git a/src/firejail/fs_trace.c b/src/firejail/fs_trace.c
index f4f5d3e81..92e4daed2 100644
--- a/src/firejail/fs_trace.c
+++ b/src/firejail/fs_trace.c
@@ -42,6 +42,7 @@ void fs_trace_preload(void) {
42 errExit("chown"); 42 errExit("chown");
43 if (chmod("/etc/ld.so.preload", S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0) 43 if (chmod("/etc/ld.so.preload", S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0)
44 errExit("chmod"); 44 errExit("chmod");
45 fs_logger("touch /etc/ls.so.preload");
45 } 46 }
46} 47}
47 48
@@ -68,6 +69,7 @@ void fs_trace(void) {
68 printf("Mount the new ld.so.preload file\n"); 69 printf("Mount the new ld.so.preload file\n");
69 if (mount(RUN_LDPRELOAD_FILE, "/etc/ld.so.preload", NULL, MS_BIND|MS_REC, NULL) < 0) 70 if (mount(RUN_LDPRELOAD_FILE, "/etc/ld.so.preload", NULL, MS_BIND|MS_REC, NULL) < 0)
70 errExit("mount bind ls.so.preload"); 71 errExit("mount bind ls.so.preload");
72 fs_logger("create /etc/ls.so.preload");
71} 73}
72 74
73 75
diff --git a/src/firejail/fs_var.c b/src/firejail/fs_var.c
index c6f989266..a53c22093 100644
--- a/src/firejail/fs_var.c
+++ b/src/firejail/fs_var.c
@@ -102,6 +102,7 @@ static void build_dirs(void) {
102 errExit("mkdir"); 102 errExit("mkdir");
103 if (chown(ptr->name, ptr->st_uid, ptr->st_gid)) 103 if (chown(ptr->name, ptr->st_uid, ptr->st_gid))
104 errExit("chown"); 104 errExit("chown");
105 fs_logger2("mkdir", ptr->name);
105 ptr = ptr->next; 106 ptr = ptr->next;
106 } 107 }
107} 108}
@@ -122,6 +123,7 @@ void fs_var_log(void) {
122 printf("Mounting tmpfs on /var/log\n"); 123 printf("Mounting tmpfs on /var/log\n");
123 if (mount("tmpfs", "/var/log", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 124 if (mount("tmpfs", "/var/log", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
124 errExit("mounting /var/log"); 125 errExit("mounting /var/log");
126 fs_logger("mount tmpfs on /var/log");
125 127
126 build_dirs(); 128 build_dirs();
127 release_all(); 129 release_all();
@@ -135,6 +137,7 @@ void fs_var_log(void) {
135 errExit("chown"); 137 errExit("chown");
136 if (chmod("/var/log/wtmp", S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH ) < 0) 138 if (chmod("/var/log/wtmp", S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH ) < 0)
137 errExit("chmod"); 139 errExit("chmod");
140 fs_logger("touch /var/log/wtmp");
138 141
139 // create an empty /var/log/btmp file 142 // create an empty /var/log/btmp file
140 fp = fopen("/var/log/btmp", "w"); 143 fp = fopen("/var/log/btmp", "w");
@@ -144,6 +147,7 @@ void fs_var_log(void) {
144 errExit("chown"); 147 errExit("chown");
145 if (chmod("/var/log/btmp", S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP) < 0) 148 if (chmod("/var/log/btmp", S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP) < 0)
146 errExit("chmod"); 149 errExit("chmod");
150 fs_logger("touch /var/log/btmp");
147 } 151 }
148 else 152 else
149 fprintf(stderr, "Warning: cannot mount tmpfs on top of /var/log\n"); 153 fprintf(stderr, "Warning: cannot mount tmpfs on top of /var/log\n");
@@ -158,6 +162,7 @@ void fs_var_lib(void) {
158 printf("Mounting tmpfs on /var/lib/dhcp\n"); 162 printf("Mounting tmpfs on /var/lib/dhcp\n");
159 if (mount("tmpfs", "/var/lib/dhcp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 163 if (mount("tmpfs", "/var/lib/dhcp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
160 errExit("mounting /var/lib/dhcp"); 164 errExit("mounting /var/lib/dhcp");
165 fs_logger("mount tmpfs on /var/lib/dhcp");
161 166
162 // isc dhcp server requires a /var/lib/dhcp/dhcpd.leases file 167 // isc dhcp server requires a /var/lib/dhcp/dhcpd.leases file
163 FILE *fp = fopen("/var/lib/dhcp/dhcpd.leases", "w"); 168 FILE *fp = fopen("/var/lib/dhcp/dhcpd.leases", "w");
@@ -169,6 +174,7 @@ void fs_var_lib(void) {
169 errExit("chown"); 174 errExit("chown");
170 if (chmod("/var/lib/dhcp/dhcpd.leases", S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) 175 if (chmod("/var/lib/dhcp/dhcpd.leases", S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH))
171 errExit("chmod"); 176 errExit("chmod");
177 fs_logger("touch /var/lib/dhcp/dhcpd.leases");
172 } 178 }
173 } 179 }
174 180
@@ -178,6 +184,7 @@ void fs_var_lib(void) {
178 printf("Mounting tmpfs on /var/lib/nginx\n"); 184 printf("Mounting tmpfs on /var/lib/nginx\n");
179 if (mount("tmpfs", "/var/lib/nginx", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 185 if (mount("tmpfs", "/var/lib/nginx", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
180 errExit("mounting /var/lib/nginx"); 186 errExit("mounting /var/lib/nginx");
187 fs_logger("mount tmpfs on /var/lib/nignx");
181 } 188 }
182 189
183 // net-snmp multiserver 190 // net-snmp multiserver
@@ -186,6 +193,7 @@ void fs_var_lib(void) {
186 printf("Mounting tmpfs on /var/lib/snmp\n"); 193 printf("Mounting tmpfs on /var/lib/snmp\n");
187 if (mount("tmpfs", "/var/lib/snmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 194 if (mount("tmpfs", "/var/lib/snmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
188 errExit("mounting /var/lib/snmp"); 195 errExit("mounting /var/lib/snmp");
196 fs_logger("mount tmpfs on /var/lib/snmp");
189 } 197 }
190 198
191 // this is where sudo remembers its state 199 // this is where sudo remembers its state
@@ -194,6 +202,7 @@ void fs_var_lib(void) {
194 printf("Mounting tmpfs on /var/lib/sudo\n"); 202 printf("Mounting tmpfs on /var/lib/sudo\n");
195 if (mount("tmpfs", "/var/lib/sudo", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 203 if (mount("tmpfs", "/var/lib/sudo", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
196 errExit("mounting /var/lib/sudo"); 204 errExit("mounting /var/lib/sudo");
205 fs_logger("mount tmpfs on /var/lib/sudo");
197 } 206 }
198} 207}
199 208
@@ -204,7 +213,8 @@ void fs_var_cache(void) {
204 if (arg_debug) 213 if (arg_debug)
205 printf("Mounting tmpfs on /var/cache/apache2\n"); 214 printf("Mounting tmpfs on /var/cache/apache2\n");
206 if (mount("tmpfs", "/var/cache/apache2", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 215 if (mount("tmpfs", "/var/cache/apache2", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
207 errExit("mounting /var/cahce/apache2"); 216 errExit("mounting /var/cache/apache2");
217 fs_logger("mount tmpfs on /var/cache/apache2");
208 } 218 }
209 219
210 if (stat("/var/cache/lighttpd", &s) == 0) { 220 if (stat("/var/cache/lighttpd", &s) == 0) {
@@ -212,6 +222,7 @@ void fs_var_cache(void) {
212 printf("Mounting tmpfs on /var/cache/lighttpd\n"); 222 printf("Mounting tmpfs on /var/cache/lighttpd\n");
213 if (mount("tmpfs", "/var/cache/lighttpd", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 223 if (mount("tmpfs", "/var/cache/lighttpd", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
214 errExit("mounting /var/cache/lighttpd"); 224 errExit("mounting /var/cache/lighttpd");
225 fs_logger("mount tmpfs on /var/cache/lighttpd");
215 226
216 struct passwd *p = getpwnam("www-data"); 227 struct passwd *p = getpwnam("www-data");
217 uid_t uid = 0; 228 uid_t uid = 0;
@@ -226,12 +237,14 @@ void fs_var_cache(void) {
226 errExit("mkdir"); 237 errExit("mkdir");
227 if (chown("/var/cache/lighttpd/compress", uid, gid) < 0) 238 if (chown("/var/cache/lighttpd/compress", uid, gid) < 0)
228 errExit("chown"); 239 errExit("chown");
240 fs_logger("mkdir /var/cache/lighttpd/compress");
229 241
230 rv = mkdir("/var/cache/lighttpd/uploads", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); 242 rv = mkdir("/var/cache/lighttpd/uploads", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
231 if (rv == -1) 243 if (rv == -1)
232 errExit("mkdir"); 244 errExit("mkdir");
233 if (chown("/var/cache/lighttpd/uploads", uid, gid) < 0) 245 if (chown("/var/cache/lighttpd/uploads", uid, gid) < 0)
234 errExit("chown"); 246 errExit("chown");
247 fs_logger("/var/cache/lighttpd/uploads");
235 } 248 }
236} 249}
237 250
@@ -257,6 +270,7 @@ void fs_var_lock(void) {
257 printf("Mounting tmpfs on /var/lock\n"); 270 printf("Mounting tmpfs on /var/lock\n");
258 if (mount("tmpfs", "/var/lock", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) 271 if (mount("tmpfs", "/var/lock", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0)
259 errExit("mounting /lock"); 272 errExit("mounting /lock");
273 fs_logger("mount tmpfs on /var/lock");
260 } 274 }
261 else { 275 else {
262 char *lnk = realpath("/var/lock", NULL); 276 char *lnk = realpath("/var/lock", NULL);
@@ -275,6 +289,7 @@ void fs_var_lock(void) {
275 if (mount("tmpfs", lnk, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) 289 if (mount("tmpfs", lnk, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0)
276 errExit("mounting /var/lock"); 290 errExit("mounting /var/lock");
277 free(lnk); 291 free(lnk);
292 fs_logger("mount tmpfs on /var/lock");
278 } 293 }
279 else { 294 else {
280 fprintf(stderr, "Warning: /var/lock not mounted\n"); 295 fprintf(stderr, "Warning: /var/lock not mounted\n");
@@ -291,6 +306,7 @@ void fs_var_tmp(void) {
291 printf("Mounting tmpfs on /var/tmp\n"); 306 printf("Mounting tmpfs on /var/tmp\n");
292 if (mount("tmpfs", "/var/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) 307 if (mount("tmpfs", "/var/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0)
293 errExit("mounting /var/tmp"); 308 errExit("mounting /var/tmp");
309 fs_logger("mount tmpfs on /var/tmp");
294 } 310 }
295 } 311 }
296 else { 312 else {
@@ -348,6 +364,7 @@ void fs_var_utmp(void) {
348 printf("Mount the new utmp file\n"); 364 printf("Mount the new utmp file\n");
349 if (mount(UTMP_FILE, "/var/run/utmp", NULL, MS_BIND|MS_REC, NULL) < 0) 365 if (mount(UTMP_FILE, "/var/run/utmp", NULL, MS_BIND|MS_REC, NULL) < 0)
350 errExit("mount bind utmp"); 366 errExit("mount bind utmp");
367 fs_logger("create /var/run/utmp");
351} 368}
352 369
353 370
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index 95238a956..f8cce219e 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -119,6 +119,7 @@ static int mkpath(const char* path, mode_t mode) {
119 errExit("strdup"); 119 errExit("strdup");
120 120
121 char* p; 121 char* p;
122 int done = 0;
122 for (p=strchr(file_path+1, '/'); p; p=strchr(p+1, '/')) { 123 for (p=strchr(file_path+1, '/'); p; p=strchr(p+1, '/')) {
123 *p='\0'; 124 *p='\0';
124 if (mkdir(file_path, mode)==-1) { 125 if (mkdir(file_path, mode)==-1) {
@@ -133,10 +134,13 @@ static int mkpath(const char* path, mode_t mode) {
133 errExit("chmod"); 134 errExit("chmod");
134 if (chown(file_path, uid, gid) == -1) 135 if (chown(file_path, uid, gid) == -1)
135 errExit("chown"); 136 errExit("chown");
137 done = 1;
136 } 138 }
137 139
138 *p='/'; 140 *p='/';
139 } 141 }
142 if (done)
143 fs_logger2("mkpath", path);
140 144
141 free(file_path); 145 free(file_path);
142 return 0; 146 return 0;
@@ -225,6 +229,7 @@ static void whitelist_path(ProfileEntry *entry) {
225 229
226 // create the path if necessary 230 // create the path if necessary
227 mkpath(path, s.st_mode); 231 mkpath(path, s.st_mode);
232 fs_logger2("whitelist", path);
228 233
229 // process directory 234 // process directory
230 if (S_ISDIR(s.st_mode)) { 235 if (S_ISDIR(s.st_mode)) {
@@ -442,6 +447,7 @@ void fs_whitelist(void) {
442 printf("Mounting tmpfs on /tmp directory\n"); 447 printf("Mounting tmpfs on /tmp directory\n");
443 if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) 448 if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0)
444 errExit("mounting tmpfs on /tmp"); 449 errExit("mounting tmpfs on /tmp");
450 fs_logger("mount tmpfs on /tmp");
445 } 451 }
446 452
447 // /media mountpoint 453 // /media mountpoint
@@ -463,9 +469,10 @@ void fs_whitelist(void) {
463 printf("Mounting tmpfs on /media directory\n"); 469 printf("Mounting tmpfs on /media directory\n");
464 if (mount("tmpfs", "/media", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 470 if (mount("tmpfs", "/media", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
465 errExit("mounting tmpfs on /media"); 471 errExit("mounting tmpfs on /media");
472 fs_logger("mount tmpfs on /media");
466 } 473 }
467 474
468 // /media mountpoint 475 // /var mountpoint
469 if (var_dir) { 476 if (var_dir) {
470 // keep a copy of real /var directory in RUN_WHITELIST_VAR_DIR 477 // keep a copy of real /var directory in RUN_WHITELIST_VAR_DIR
471 int rv = mkdir(RUN_WHITELIST_VAR_DIR, S_IRWXU | S_IRWXG | S_IRWXO); 478 int rv = mkdir(RUN_WHITELIST_VAR_DIR, S_IRWXU | S_IRWXG | S_IRWXO);
@@ -484,6 +491,7 @@ void fs_whitelist(void) {
484 printf("Mounting tmpfs on /var directory\n"); 491 printf("Mounting tmpfs on /var directory\n");
485 if (mount("tmpfs", "/var", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 492 if (mount("tmpfs", "/var", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
486 errExit("mounting tmpfs on /var"); 493 errExit("mounting tmpfs on /var");
494 fs_logger("mount tmpfs on /var");
487 } 495 }
488 496
489 // /dev mountpoint 497 // /dev mountpoint
@@ -505,6 +513,7 @@ void fs_whitelist(void) {
505 printf("Mounting tmpfs on /dev directory\n"); 513 printf("Mounting tmpfs on /dev directory\n");
506 if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 514 if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
507 errExit("mounting tmpfs on /dev"); 515 errExit("mounting tmpfs on /dev");
516 fs_logger("mount tmpfs on /dev");
508 } 517 }
509 518
510 // /opt mountpoint 519 // /opt mountpoint
@@ -526,6 +535,7 @@ void fs_whitelist(void) {
526 printf("Mounting tmpfs on /opt directory\n"); 535 printf("Mounting tmpfs on /opt directory\n");
527 if (mount("tmpfs", "/opt", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 536 if (mount("tmpfs", "/opt", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
528 errExit("mounting tmpfs on /opt"); 537 errExit("mounting tmpfs on /opt");
538 fs_logger("mount tmpfs on /opt");
529 } 539 }
530 540
531 // go through profile rules again, and interpret whitelist commands 541 // go through profile rules again, and interpret whitelist commands
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 2981683aa..a6e95e963 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -340,7 +340,15 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
340 caps_print_filter_name(argv[i] + 13); 340 caps_print_filter_name(argv[i] + 13);
341 exit(0); 341 exit(0);
342 } 342 }
343 343 else if (strncmp(argv[i], "--fs.print=", 11) == 0) {
344 // join sandbox by pid or by name
345 pid_t pid;
346 if (read_pid(argv[i] + 11, &pid) == 0)
347 fs_logger_print_log(pid);
348 else
349 fs_logger_print_log_name(argv[i] + 11);
350 exit(0);
351 }
344 else if (strncmp(argv[i], "--dns.print=", 12) == 0) { 352 else if (strncmp(argv[i], "--dns.print=", 12) == 0) {
345 // join sandbox by pid or by name 353 // join sandbox by pid or by name
346 pid_t pid; 354 pid_t pid;
diff --git a/src/firejail/pulseaudio.c b/src/firejail/pulseaudio.c
index 6ead5799c..3d54751c7 100644
--- a/src/firejail/pulseaudio.c
+++ b/src/firejail/pulseaudio.c
@@ -45,6 +45,7 @@ static void disable_file(const char *path, const char *file) {
45 if (mount(RUN_RO_FILE, fname, "none", MS_BIND, "mode=400,gid=0") < 0) 45 if (mount(RUN_RO_FILE, fname, "none", MS_BIND, "mode=400,gid=0") < 0)
46 errExit("disable file"); 46 errExit("disable file");
47 } 47 }
48 fs_logger2("blacklist", fname);
48 49
49doexit: 50doexit:
50 free(fname); 51 free(fname);
diff --git a/src/firejail/restrict_users.c b/src/firejail/restrict_users.c
index 50a9a9b89..ec65005ba 100644
--- a/src/firejail/restrict_users.c
+++ b/src/firejail/restrict_users.c
@@ -59,40 +59,6 @@ static USER_LIST *ulist_find(const char *user) {
59 return NULL; 59 return NULL;
60} 60}
61 61
62static int mkpath(const char* path) {
63 assert(path && *path);
64
65 // work on a copy of the path
66 char *file_path = strdup(path);
67 if (!file_path)
68 errExit("strdup");
69
70 char* p;
71 for (p=strchr(file_path+1, '/'); p; p=strchr(p+1, '/')) {
72 *p='\0';
73 if (mkdir(file_path, 0755)==-1) {
74 if (errno != EEXIST) {
75 *p='/';
76 free(file_path);
77 return -1;
78 }
79 }
80 else {
81 if (chmod(file_path, 0755) == -1)
82 errExit("chmod");
83 if (chown(file_path, 0, 0) == -1)
84 errExit("chown");
85 }
86
87 *p='/';
88 }
89
90 free(file_path);
91 return 0;
92}
93
94
95
96static void sanitize_home(void) { 62static void sanitize_home(void) {
97 assert(getuid() != 0); // this code works only for regular users 63 assert(getuid() != 0); // this code works only for regular users
98 64
@@ -117,6 +83,7 @@ static void sanitize_home(void) {
117 // mount tmpfs in the new home 83 // mount tmpfs in the new home
118 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 84 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
119 errExit("mount tmpfs"); 85 errExit("mount tmpfs");
86 fs_logger("mount tmpfs on /home");
120 87
121 // create user home directory 88 // create user home directory
122 if (mkdir(cfg.homedir, 0755) == -1) { 89 if (mkdir(cfg.homedir, 0755) == -1) {
@@ -125,6 +92,7 @@ static void sanitize_home(void) {
125 if (mkdir(cfg.homedir, 0755) == -1) 92 if (mkdir(cfg.homedir, 0755) == -1)
126 errExit("mkdir"); 93 errExit("mkdir");
127 } 94 }
95 fs_logger2("mkdir", cfg.homedir);
128 96
129 // set mode and ownership 97 // set mode and ownership
130 if (chown(cfg.homedir, s.st_uid, s.st_gid) == -1) 98 if (chown(cfg.homedir, s.st_uid, s.st_gid) == -1)
@@ -218,6 +186,7 @@ static void sanitize_passwd(void) {
218 // mount-bind tne new password file 186 // mount-bind tne new password file
219 if (mount(RUN_PASSWD_FILE, "/etc/passwd", "none", MS_BIND, "mode=400,gid=0") < 0) 187 if (mount(RUN_PASSWD_FILE, "/etc/passwd", "none", MS_BIND, "mode=400,gid=0") < 0)
220 errExit("mount"); 188 errExit("mount");
189 fs_logger("create /etc/passwd");
221 190
222 return; 191 return;
223 192
@@ -344,6 +313,7 @@ static void sanitize_group(void) {
344 // mount-bind tne new group file 313 // mount-bind tne new group file
345 if (mount(RUN_GROUP_FILE, "/etc/group", "none", MS_BIND, "mode=400,gid=0") < 0) 314 if (mount(RUN_GROUP_FILE, "/etc/group", "none", MS_BIND, "mode=400,gid=0") < 0)
346 errExit("mount"); 315 errExit("mount");
316 fs_logger("create /etc/group");
347 317
348 return; 318 return;
349 319
@@ -367,6 +337,7 @@ void restrict_users(void) {
367 // mount tmpfs on top of /home in order to hide it 337 // mount tmpfs on top of /home in order to hide it
368 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 338 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
369 errExit("mount tmpfs"); 339 errExit("mount tmpfs");
340 fs_logger("mount tmpfs on /home");
370 } 341 }
371 sanitize_passwd(); 342 sanitize_passwd();
372 sanitize_group(); 343 sanitize_group();
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 2827ca9d3..5ae43dbd1 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -271,6 +271,7 @@ int sandbox(void* sandbox_arg) {
271 if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) { 271 if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) {
272 chk_chroot(); 272 chk_chroot();
273 } 273 }
274 fs_logger("install mount namespace");
274 275
275 //**************************** 276 //****************************
276 // netfilter etc. 277 // netfilter etc.
@@ -400,7 +401,7 @@ int sandbox(void* sandbox_arg) {
400 pulseaudio_disable(); 401 pulseaudio_disable();
401 else 402 else
402 pulseaudio_init(); 403 pulseaudio_init();
403 404
404 //**************************** 405 //****************************
405 // networking 406 // networking
406 //**************************** 407 //****************************
@@ -468,6 +469,8 @@ int sandbox(void* sandbox_arg) {
468 469
469 // if any dns server is configured, it is time to set it now 470 // if any dns server is configured, it is time to set it now
470 fs_resolvconf(); 471 fs_resolvconf();
472 fs_logger_print();
473 fs_logger_change_owner();
471 474
472 // print network configuration 475 // print network configuration
473 if (!arg_quiet) { 476 if (!arg_quiet) {
diff --git a/src/firejail/usage.c b/src/firejail/usage.c
index d8f6d6849..70b9cf24e 100644
--- a/src/firejail/usage.c
+++ b/src/firejail/usage.c
@@ -83,7 +83,11 @@ void usage(void) {
83 printf("\t--dns.print=pid - print DNS configuration of the sandbox identified.\n"); 83 printf("\t--dns.print=pid - print DNS configuration of the sandbox identified.\n");
84 printf("\t\tby PID.\n\n"); 84 printf("\t\tby PID.\n\n");
85 85
86 printf("\t--env=name=value - set environment variable in the new sandbox\n"); 86 printf("\t--env=name=value - set environment variable in the new sandbox\n\n");
87 printf("\t--fs.print=name - print the filesystem log for the sandbox identified\n");
88 printf("\t\tby name.\n\n");
89 printf("\t--fs.print=pid - print the filesystem log for the sandbox identified\n");
90 printf("\t\tby PID.\n\n");
87 91
88 printf("\t--help, -? - this help screen.\n\n"); 92 printf("\t--help, -? - this help screen.\n\n");
89 printf("\t--hostname=name - set sandbox hostname.\n\n"); 93 printf("\t--hostname=name - set sandbox hostname.\n\n");
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 45f7ec364..6c7476be6 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -84,6 +84,7 @@ int mkpath_as_root(const char* path) {
84 errExit("strdup"); 84 errExit("strdup");
85 85
86 char* p; 86 char* p;
87 int done = 0;
87 for (p=strchr(file_path+1, '/'); p; p=strchr(p+1, '/')) { 88 for (p=strchr(file_path+1, '/'); p; p=strchr(p+1, '/')) {
88 *p='\0'; 89 *p='\0';
89 if (mkdir(file_path, 0755)==-1) { 90 if (mkdir(file_path, 0755)==-1) {
@@ -98,11 +99,14 @@ int mkpath_as_root(const char* path) {
98 errExit("chmod"); 99 errExit("chmod");
99 if (chown(file_path, 0, 0) == -1) 100 if (chown(file_path, 0, 0) == -1)
100 errExit("chown"); 101 errExit("chown");
102 done = 1;
101 } 103 }
102 104
103 *p='/'; 105 *p='/';
104 } 106 }
105 107 if (done)
108 fs_logger2("mkpath", path);
109
106 free(file_path); 110 free(file_path);
107 return 0; 111 return 0;
108} 112}
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index 4f9f0cba9..de03af56c 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -338,6 +338,35 @@ Example:
338$ firejail \-\-env=LD_LIBRARY_PATH=/opt/test/lib 338$ firejail \-\-env=LD_LIBRARY_PATH=/opt/test/lib
339 339
340.TP 340.TP
341\fB\-\-fs.print=name
342Print the filesystem log for the sandbox identified by name.
343.br
344
345.br
346Example:
347.br
348$ firejail \-\-name=mygame \-\-caps.drop=all warzone2100 &
349.br
350[...]
351.br
352$ firejail \-\-fs.print=mygame
353
354.TP
355\fB\-\-fs.print=pid
356Print the filesystem log for a sandbox identified by PID.
357.br
358
359.br
360Example:
361.br
362$ firejail \-\-list
363.br
3643272:netblue:firejail \-\-private firefox
365.br
366$ firejail \-\-fs.print=3272
367
368
369.TP
341\fB\-?\fR, \fB\-\-help\fR 370\fB\-?\fR, \fB\-\-help\fR
342Print options end exit. 371Print options end exit.
343 372
diff --git a/todo b/todo
index 553933f00..b7754f7ef 100644
--- a/todo
+++ b/todo
@@ -139,3 +139,11 @@ drwxr-xr-x 3 65534 65534 60 Nov 25 08:09 ..
139-rw-r--r-- 1 netblue netblue 3392 Nov 25 08:09 .bashrc 139-rw-r--r-- 1 netblue netblue 3392 Nov 25 08:09 .bashrc
140dr-x------ 2 65534 65534 40 Nov 24 17:53 .mozilla 140dr-x------ 2 65534 65534 40 Nov 24 17:53 .mozilla
141-rw------- 1 netblue netblue 51 Nov 25 08:09 .Xauthority 141-rw------- 1 netblue netblue 51 Nov 25 08:09 .Xauthority
142
143
14419. move from tmpfs to blacklist
145mount tmpfs on /sys/firmware
146mount tmpfs on /sys/hypervisor
147mount tmpfs on /sys/fs
148mount tmpfs on /sys/module
149mount tmpfs on /sys/power