aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md9
-rw-r--r--RELNOTES1
-rw-r--r--src/firejail/firejail.h2
-rw-r--r--src/firejail/main.c44
-rw-r--r--src/firejail/preproc.c80
-rw-r--r--src/firejail/profile.c23
-rw-r--r--src/firejail/usage.c1
-rw-r--r--src/man/firejail.txt13
-rwxr-xr-xtest/profiles/test-profile.exp1
9 files changed, 168 insertions, 6 deletions
diff --git a/README.md b/README.md
index 6f1c892aa..7edad942a 100644
--- a/README.md
+++ b/README.md
@@ -174,6 +174,15 @@ Check the status of the latest build here: https://travis-ci.org/netblue30/firej
174 amd64, i386 and x32 system calls are blocked as well as chang‐ 174 amd64, i386 and x32 system calls are blocked as well as chang‐
175 ing the execution domain with personality(2) system call. 175 ing the execution domain with personality(2) system call.
176 176
177 --profile.print=name|pid
178 Print the name of the profile file for the sandbox identified
179 by name or or PID.
180
181 Example:
182 $ firejail --profile.print=browser
183 /etc/firejail/firefox.profile
184
185
177````` 186`````
178 187
179## /etc/firejail/firejail.config 188## /etc/firejail/firejail.config
diff --git a/RELNOTES b/RELNOTES
index a54438411..43ec0a142 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -6,6 +6,7 @@ firejail (0.9.50~rc1) baseline; urgency=low
6 * feature: private /lib directory (--private-lib) 6 * feature: private /lib directory (--private-lib)
7 * feature: disable CDROM/DVD drive (--nodvd) 7 * feature: disable CDROM/DVD drive (--nodvd)
8 * feature: disable DVB devices (--notv) 8 * feature: disable DVB devices (--notv)
9 * feature: --profile.print
9 * enhancement: print all seccomp filters under --debug 10 * enhancement: print all seccomp filters under --debug
10 * enhancement: /proc/sys mounting 11 * enhancement: /proc/sys mounting
11 * enhancement: rework IP address assingment for --net options 12 * enhancement: rework IP address assingment for --net options
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 60a43a600..75450fe0f 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -34,6 +34,7 @@
34#define RUN_FIREJAIL_X11_DIR "/run/firejail/x11" 34#define RUN_FIREJAIL_X11_DIR "/run/firejail/x11"
35#define RUN_FIREJAIL_NETWORK_DIR "/run/firejail/network" 35#define RUN_FIREJAIL_NETWORK_DIR "/run/firejail/network"
36#define RUN_FIREJAIL_BANDWIDTH_DIR "/run/firejail/bandwidth" 36#define RUN_FIREJAIL_BANDWIDTH_DIR "/run/firejail/bandwidth"
37#define RUN_FIREJAIL_PROFILE_DIR "/run/firejail/profile"
37#define RUN_NETWORK_LOCK_FILE "/run/firejail/firejail.lock" 38#define RUN_NETWORK_LOCK_FILE "/run/firejail/firejail.lock"
38#define RUN_RO_DIR "/run/firejail/firejail.ro.dir" 39#define RUN_RO_DIR "/run/firejail/firejail.ro.dir"
39#define RUN_RO_FILE "/run/firejail/firejail.ro.file" 40#define RUN_RO_FILE "/run/firejail/firejail.ro.file"
@@ -410,6 +411,7 @@ void net_config_interface(const char *dev, uint32_t ip, uint32_t mask, int mtu);
410// preproc.c 411// preproc.c
411void preproc_build_firejail_dir(void); 412void preproc_build_firejail_dir(void);
412void preproc_mount_mnt_dir(void); 413void preproc_mount_mnt_dir(void);
414void preproc_clean_run(void);
413 415
414// fs.c 416// fs.c
415// blacklist files or directoies by mounting empty files on top of them 417// blacklist files or directoies by mounting empty files on top of them
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 3f805a7e0..c317aa477 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -130,15 +130,22 @@ unsigned long long start_timestamp;
130 130
131static void set_name_file(pid_t pid); 131static void set_name_file(pid_t pid);
132static void delete_name_file(pid_t pid); 132static void delete_name_file(pid_t pid);
133static void delete_profile_file(pid_t pid);
133static void delete_x11_file(pid_t pid); 134static void delete_x11_file(pid_t pid);
134 135
135void clear_run_files(pid_t pid) { 136void clear_run_files(pid_t pid) {
136 bandwidth_del_run_file(pid); // bandwidth file 137 bandwidth_del_run_file(pid); // bandwidth file
137 network_del_run_file(pid); // network map file 138 network_del_run_file(pid); // network map file
138 delete_name_file(pid); 139 delete_name_file(pid);
140 delete_profile_file(pid);
139 delete_x11_file(pid); 141 delete_x11_file(pid);
140} 142}
141 143
144static void clear_atexit(void) {
145 EUID_ROOT();
146 clear_run_files(getpid());
147}
148
142static void myexit(int rv) { 149static void myexit(int rv) {
143 logmsg("exiting..."); 150 logmsg("exiting...");
144 if (!arg_command && !arg_quiet) 151 if (!arg_command && !arg_quiet)
@@ -465,6 +472,26 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
465 exit(0); 472 exit(0);
466 } 473 }
467#endif 474#endif
475 else if (strncmp(argv[i], "--profile.print=", 16) == 0) {
476 pid_t pid = read_pid(argv[i] + 16);
477
478 // print /run/firejail/profile/<PID> file
479 char *fname;
480 if (asprintf(&fname, RUN_FIREJAIL_PROFILE_DIR "/%d", pid) == -1)
481 errExit("asprintf");
482 FILE *fp = fopen(fname, "r");
483 if (!fp) {
484 fprintf(stderr, "Error: sandbox %s not found\n", argv[i] + 16);
485 exit(1);
486 }
487#define MAXBUF 4096
488 char buf[MAXBUF];
489 if (fgets(buf, MAXBUF, fp))
490 printf("%s", buf);
491 fclose(fp);
492 exit(0);
493
494 }
468 else if (strncmp(argv[i], "--cpu.print=", 12) == 0) { 495 else if (strncmp(argv[i], "--cpu.print=", 12) == 0) {
469 // join sandbox by pid or by name 496 // join sandbox by pid or by name
470 pid_t pid = read_pid(argv[i] + 12); 497 pid_t pid = read_pid(argv[i] + 12);
@@ -738,6 +765,15 @@ static void delete_name_file(pid_t pid) {
738 free(fname); 765 free(fname);
739} 766}
740 767
768static void delete_profile_file(pid_t pid) {
769 char *fname;
770 if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_PROFILE_DIR, pid) == -1)
771 errExit("asprintf");
772 int rv = unlink(fname);
773 (void) rv;
774 free(fname);
775}
776
741void set_x11_file(pid_t pid, int display) { 777void set_x11_file(pid_t pid, int display) {
742 char *fname; 778 char *fname;
743 if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_X11_DIR, pid) == -1) 779 if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_X11_DIR, pid) == -1)
@@ -825,12 +861,14 @@ int main(int argc, char **argv) {
825 char *custom_profile_dir = NULL; // custom profile directory 861 char *custom_profile_dir = NULL; // custom profile directory
826 862
827 863
864 atexit(clear_atexit);
865
828 // get starting timestamp 866 // get starting timestamp
829 start_timestamp = getticks(); 867 start_timestamp = getticks();
830 868
831
832 // build /run/firejail directory structure 869 // build /run/firejail directory structure
833 preproc_build_firejail_dir(); 870 preproc_build_firejail_dir();
871 preproc_clean_run();
834 872
835 if (check_arg(argc, argv, "--quiet")) 873 if (check_arg(argc, argv, "--quiet"))
836 arg_quiet = 1; 874 arg_quiet = 1;
@@ -2554,14 +2592,10 @@ int main(int argc, char **argv) {
2554 close(lockfd); 2592 close(lockfd);
2555 } 2593 }
2556 2594
2557 // create name file under /run/firejail
2558
2559
2560 // handle CTRL-C in parent 2595 // handle CTRL-C in parent
2561 signal (SIGINT, my_handler); 2596 signal (SIGINT, my_handler);
2562 signal (SIGTERM, my_handler); 2597 signal (SIGTERM, my_handler);
2563 2598
2564
2565 // wait for the child to finish 2599 // wait for the child to finish
2566 EUID_USER(); 2600 EUID_USER();
2567 int status = 0; 2601 int status = 0;
diff --git a/src/firejail/preproc.c b/src/firejail/preproc.c
index 0b447e03b..42502008e 100644
--- a/src/firejail/preproc.c
+++ b/src/firejail/preproc.c
@@ -20,6 +20,8 @@
20#include "firejail.h" 20#include "firejail.h"
21#include <sys/mount.h> 21#include <sys/mount.h>
22#include <sys/stat.h> 22#include <sys/stat.h>
23#include <sys/types.h>
24#include <dirent.h>
23 25
24static int tmpfs_mounted = 0; 26static int tmpfs_mounted = 0;
25 27
@@ -48,6 +50,10 @@ void preproc_build_firejail_dir(void) {
48 create_empty_dir_as_root(RUN_FIREJAIL_NAME_DIR, 0755); 50 create_empty_dir_as_root(RUN_FIREJAIL_NAME_DIR, 0755);
49 } 51 }
50 52
53 if (stat(RUN_FIREJAIL_PROFILE_DIR, &s)) {
54 create_empty_dir_as_root(RUN_FIREJAIL_PROFILE_DIR, 0755);
55 }
56
51 if (stat(RUN_FIREJAIL_X11_DIR, &s)) { 57 if (stat(RUN_FIREJAIL_X11_DIR, &s)) {
52 create_empty_dir_as_root(RUN_FIREJAIL_X11_DIR, 0755); 58 create_empty_dir_as_root(RUN_FIREJAIL_X11_DIR, 0755);
53 } 59 }
@@ -98,3 +104,77 @@ void preproc_mount_mnt_dir(void) {
98 errExit("set_perms"); 104 errExit("set_perms");
99 } 105 }
100} 106}
107
108// clean run directory
109void preproc_clean_run(void) {
110 int max_pids=32769;
111 int start_pid = 100;
112 // extract real max_pids
113 FILE *fp = fopen("/proc/sys/kernel/pid_max", "r");
114 if (fp) {
115 int val;
116 if (fscanf(fp, "%d", &val) == 1) {
117 if (val >= max_pids)
118 max_pids = val + 1;
119 }
120 fclose(fp);
121 }
122 int *pidarr = malloc(max_pids * sizeof(int));
123 if (!pidarr)
124 errExit("malloc");
125
126 memset(pidarr, 0, max_pids * sizeof(int));
127
128 // open /proc directory
129 DIR *dir;
130 if (!(dir = opendir("/proc"))) {
131 // sleep 2 seconds and try again
132 sleep(2);
133 if (!(dir = opendir("/proc"))) {
134 fprintf(stderr, "Error: cannot open /proc directory\n");
135 exit(1);
136 }
137 }
138
139 // read /proc and populate pidarr with all active processes
140 struct dirent *entry;
141 char *end;
142 while ((entry = readdir(dir)) != NULL) {
143 pid_t pid = strtol(entry->d_name, &end, 10);
144 pid %= max_pids;
145 if (end == entry->d_name || *end)
146 continue;
147
148 if (pid < start_pid)
149 continue;
150 pidarr[pid] = 1;
151 }
152 closedir(dir);
153
154 // open /run/firejail/profile directory
155 if (!(dir = opendir(RUN_FIREJAIL_PROFILE_DIR))) {
156 // sleep 2 seconds and try again
157 sleep(2);
158 if (!(dir = opendir(RUN_FIREJAIL_PROFILE_DIR))) {
159 fprintf(stderr, "Error: cannot open %s directory\n", RUN_FIREJAIL_PROFILE_DIR);
160 exit(1);
161 }
162 }
163
164 // read /run/firejail/profile directory and clean leftover files
165 while ((entry = readdir(dir)) != NULL) {
166 pid_t pid = strtol(entry->d_name, &end, 10);
167 pid %= max_pids;
168 if (end == entry->d_name || *end)
169 continue;
170
171 if (pid < start_pid)
172 continue;
173 if (pidarr[pid] == 0)
174 clear_run_files(pid);
175 }
176 closedir(dir);
177
178 free(pidarr);
179}
180
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index fc390c83a..e61f59f46 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -1193,6 +1193,29 @@ void profile_read(const char *fname) {
1193 exit(1); 1193 exit(1);
1194 } 1194 }
1195 1195
1196 // save the name of the file for --profile.print option
1197 if (include_level == 0) {
1198 char *runfile;
1199 if (asprintf(&runfile, "%s/%d", RUN_FIREJAIL_PROFILE_DIR, getpid()) == -1)
1200 errExit("asprintf");
1201
1202 EUID_ROOT();
1203 // the file is deleted first
1204 FILE *fp = fopen(runfile, "w");
1205 if (!fp) {
1206 fprintf(stderr, "Error: cannot create %s\n", runfile);
1207 exit(1);
1208 }
1209 fprintf(fp, "%s\n", fname);
1210
1211 // mode and ownership
1212 SET_PERMS_STREAM(fp, 0, 0, 0644);
1213 fclose(fp);
1214 EUID_USER();
1215 free(runfile);
1216 }
1217
1218
1196 int msg_printed = 0; 1219 int msg_printed = 0;
1197 1220
1198 // read the file line by line 1221 // read the file line by line
diff --git a/src/firejail/usage.c b/src/firejail/usage.c
index 10e6ab687..fc7dbd69c 100644
--- a/src/firejail/usage.c
+++ b/src/firejail/usage.c
@@ -159,6 +159,7 @@ void usage(void) {
159 printf(" --private-tmp - mount a tmpfs on top of /tmp directory.\n"); 159 printf(" --private-tmp - mount a tmpfs on top of /tmp directory.\n");
160 printf(" --private-opt=file,directory - build a new /opt in a temporary filesystem.\n"); 160 printf(" --private-opt=file,directory - build a new /opt in a temporary filesystem.\n");
161 printf(" --profile=filename - use a custom profile.\n"); 161 printf(" --profile=filename - use a custom profile.\n");
162 printf(" --profile.print=name|pid - print the name of profile file.\n");
162 printf(" --profile-path=directory - use this directory to look for profile files.\n"); 163 printf(" --profile-path=directory - use this directory to look for profile files.\n");
163 printf(" --protocol=protocol,protocol,protocol - enable protocol filter.\n"); 164 printf(" --protocol=protocol,protocol,protocol - enable protocol filter.\n");
164 printf(" --protocol.print=name|pid - print the protocol filter.\n"); 165 printf(" --protocol.print=name|pid - print the protocol filter.\n");
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index 9ae5d6782..a70f662fd 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -1424,6 +1424,19 @@ Example:
1424$ firejail \-\-profile=myprofile 1424$ firejail \-\-profile=myprofile
1425 1425
1426.TP 1426.TP
1427\fB\-\-profile.print=name|pid
1428Print the name of the profile file for the sandbox identified by name or or PID.
1429.br
1430
1431.br
1432Example:
1433.br
1434$ firejail \-\-profile.print=browser
1435.br
1436/etc/firejail/firefox.profile
1437.br
1438
1439.TP
1427\fB\-\-profile-path=directory 1440\fB\-\-profile-path=directory
1428Use this directory to look for profile files. Use an absolute path or a path in the home directory starting with ~/. 1441Use this directory to look for profile files. Use an absolute path or a path in the home directory starting with ~/.
1429For more information, see \fBSECURITY PROFILES\fR section below and \fBRELOCATING PROFILE FILES\fR in 1442For more information, see \fBSECURITY PROFILES\fR section below and \fBRELOCATING PROFILE FILES\fR in
diff --git a/test/profiles/test-profile.exp b/test/profiles/test-profile.exp
index 6bc47f33f..63fb3a150 100755
--- a/test/profiles/test-profile.exp
+++ b/test/profiles/test-profile.exp
@@ -18,6 +18,5 @@ expect {
18 timeout {puts "TESTING ERROR 0\n";exit} 18 timeout {puts "TESTING ERROR 0\n";exit}
19 "done" 19 "done"
20} 20}
21send -- "exit\r"
22after 100 21after 100
23puts "\n" 22puts "\n"