aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
6 files changed, 158 insertions, 5 deletions
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