aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2015-08-23 07:17:30 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2015-08-23 07:17:30 -0400
commit73c5236e195332ef0b8792712d4ff5c24399c19c (patch)
treeadf41f9fe29b22c89cd430ec8302b23d9001cfc4 /src
parentsupport net none in profile files (diff)
downloadfirejail-73c5236e195332ef0b8792712d4ff5c24399c19c.tar.gz
firejail-73c5236e195332ef0b8792712d4ff5c24399c19c.tar.zst
firejail-73c5236e195332ef0b8792712d4ff5c24399c19c.zip
if a sandbox is already running, the program is started directly
Diffstat (limited to 'src')
-rw-r--r--src/firejail/firejail.h4
-rw-r--r--src/firejail/main.c10
-rw-r--r--src/firejail/no_sandbox.c119
3 files changed, 131 insertions, 2 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 3acaeb6fb..321f0e830 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -358,5 +358,9 @@ void network_shm_set_file(pid_t pid);
358void fs_check_etc_list(void); 358void fs_check_etc_list(void);
359void fs_private_etc_list(void); 359void fs_private_etc_list(void);
360 360
361// no_sandbox.c
362int check_kernel_procs(void);
363void run_no_sandbox(int argc, char **argv);
364
361#endif 365#endif
362 366
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 14a5d9d47..9acfb254f 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -242,12 +242,18 @@ int main(int argc, char **argv) {
242 int arg_ipc = 0; 242 int arg_ipc = 0;
243 int arg_cgroup = 0; 243 int arg_cgroup = 0;
244 int custom_profile = 0; // custom profile loaded 244 int custom_profile = 0; // custom profile loaded
245
246 // if a sandbox is already running, start the program directly without sandboxing
247 if (check_kernel_procs() == 0) {
248 run_no_sandbox(argc, argv);
249 // it will never get here!
250 assert(0);
251 }
245 252
246 // initialize globals 253 // initialize globals
247 init_cfg(); 254 init_cfg();
248 cfg.original_argv = argv; 255 cfg.original_argv = argv;
249 cfg.original_argc = argc; 256 cfg.original_argc = argc;
250
251 257
252 // initialize random number generator 258 // initialize random number generator
253 sandbox_pid = getpid(); 259 sandbox_pid = getpid();
@@ -276,7 +282,7 @@ int main(int argc, char **argv) {
276 // check --output option and execute it; 282 // check --output option and execute it;
277 check_output(argc, argv); // the function will not return if --output option was found 283 check_output(argc, argv); // the function will not return if --output option was found
278 } 284 }
279 285
280 // parse arguments 286 // parse arguments
281 for (i = 1; i < argc; i++) { 287 for (i = 1; i < argc; i++) {
282 //************************************* 288 //*************************************
diff --git a/src/firejail/no_sandbox.c b/src/firejail/no_sandbox.c
new file mode 100644
index 000000000..9dc01435f
--- /dev/null
+++ b/src/firejail/no_sandbox.c
@@ -0,0 +1,119 @@
1#include "firejail.h"
2#include <sys/types.h>
3#include <sys/stat.h>
4#include <unistd.h>
5
6// check process space for kernel processes
7// return 1 if found, 0 if not found
8int check_kernel_procs(void) {
9 char *kern_proc[] = {
10 "kthreadd",
11 "ksoftirqd",
12 "kworker",
13 "rcu_sched",
14 "rcu_bh",
15 NULL // NULL terminated list
16 };
17 int i;
18
19 // look at the first 10 processes
20 // if a kernel process is found, return 1
21 for (i = 1; i <= 10; i++) {
22 struct stat s;
23 char *fname;
24 if (asprintf(&fname, "/proc/%d/comm", i) == -1)
25 errExit("asprintf");
26 if (stat(fname, &s) == -1) {
27 free(fname);
28 continue;
29 }
30
31 // open file
32 FILE *fp = fopen(fname, "r");
33 if (!fp) {
34 fprintf(stderr, "Warning: cannot open %s\n", fname);
35 free(fname);
36 continue;
37 }
38
39 // read file
40 char buf[100];
41 if (fgets(buf, 10, fp) == NULL) {
42 fprintf(stderr, "Warning: cannot read %s\n", fname);
43 fclose(fp);
44 free(fname);
45 continue;
46 }
47 // clean /n
48 char *ptr;
49 if ((ptr = strchr(buf, '\n')) != NULL)
50 *ptr = '\0';
51
52 // check process name against the kernel list
53 int j = 0;
54 while (kern_proc[j] != NULL) {
55 if (strncmp(buf, kern_proc[j], strlen(kern_proc[j])) == 0) {
56 fclose(fp);
57 free(fname);
58 return 1;
59 }
60 j++;
61 }
62
63 fclose(fp);
64 free(fname);
65 }
66
67 return 0;
68}
69
70void run_no_sandbox(int argc, char **argv) {
71 // drop privileges
72 int rv = setgroups(0, NULL); // this could fail
73 (void) rv;
74 if (setgid(getgid()) < 0)
75 errExit("setgid/getgid");
76 if (setuid(getuid()) < 0)
77 errExit("setuid/getuid");
78
79
80 // build command
81 char *command = NULL;
82 int allocated = 0;
83 if (argc == 1)
84 command = "/bin/bash";
85 else {
86 // calculate length
87 int len = 0;
88 int i;
89 for (i = 1; i < argc; i++) {
90 if (*argv[i] == '-')
91 continue;
92 break;
93 }
94 int start_index = i;
95 for (i = start_index; i < argc; i++)
96 len += strlen(argv[i]) + 1;
97
98 // allocate
99 command = malloc(len + 1);
100 if (!command)
101 errExit("malloc");
102 memset(command, 0, len + 1);
103 allocated = 1;
104
105 // copy
106 for (i = start_index; i < argc; i++) {
107 strcat(command, argv[i]);
108 strcat(command, " ");
109 }
110 }
111
112 // start the program in /bin/sh
113 fprintf(stderr, "Warning: an existing sandbox was detected. "
114 "%s will run without any additional sandboxing features in a /bin/sh shell\n", command);
115 system(command);
116 if (allocated)
117 free(command);
118 exit(1);
119}