aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2015-11-13 07:50:40 -0500
committerLibravatar netblue30 <netblue30@yahoo.com>2015-11-13 07:50:40 -0500
commit4a8a6eff0ee1633b28f0302e5bd356790110b28b (patch)
treea6a2dccce6f7ca30cb1dc144cb224243f5903f59 /src
parentremoved exclude-token from profile include (diff)
downloadfirejail-4a8a6eff0ee1633b28f0302e5bd356790110b28b.tar.gz
firejail-4a8a6eff0ee1633b28f0302e5bd356790110b28b.tar.zst
firejail-4a8a6eff0ee1633b28f0302e5bd356790110b28b.zip
support for kde and server programs
Diffstat (limited to 'src')
-rw-r--r--src/firejail/sandbox.c193
1 files changed, 128 insertions, 65 deletions
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 81d09ed34..582a4f520 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -25,6 +25,8 @@
25#include <sys/prctl.h> 25#include <sys/prctl.h>
26#include <sys/time.h> 26#include <sys/time.h>
27#include <sys/resource.h> 27#include <sys/resource.h>
28#include <sys/types.h>
29#include <dirent.h>
28 30
29#include <sched.h> 31#include <sched.h>
30#ifndef CLONE_NEWUSER 32#ifndef CLONE_NEWUSER
@@ -124,6 +126,119 @@ static void chk_chroot(void) {
124 exit(1); 126 exit(1);
125} 127}
126 128
129static void monitor_application(pid_t app_pid) {
130 while (app_pid) {
131 sleep(1);
132
133 int status;
134 unsigned rv = waitpid(app_pid, &status, 0);
135 if (arg_debug)
136 printf("Sandbox monitor: waitpid %u retval %d status %d\n", app_pid, rv, status);
137
138 DIR *dir;
139 if (!(dir = opendir("/proc"))) {
140 // sleep 2 seconds and try again
141 sleep(2);
142 if (!(dir = opendir("/proc"))) {
143 fprintf(stderr, "Error: cannot open /proc directory\n");
144 exit(1);
145 }
146 }
147
148 struct dirent *entry;
149 app_pid = 0;
150 while ((entry = readdir(dir)) != NULL) {
151 char *end;
152 unsigned pid;
153 if (sscanf(entry->d_name, "%u", &pid) != 1)
154 continue;
155 if (pid == 1)
156 continue;
157 app_pid = pid;
158 break;
159 }
160 closedir(dir);
161
162 if (app_pid != 0 && arg_debug)
163 printf("Sandbox monitor: monitoring %u\n", app_pid);
164 }
165}
166
167
168static void start_application(void) {
169 //****************************************
170 // start the program without using a shell
171 //****************************************
172 if (arg_shell_none) {
173 if (arg_debug) {
174 int i;
175 for (i = cfg.original_program_index; i < cfg.original_argc; i++) {
176 if (cfg.original_argv[i] == NULL)
177 break;
178 printf("execvp argument %d: %s\n", i - cfg.original_program_index, cfg.original_argv[i]);
179 }
180 }
181
182 if (!arg_command && !arg_quiet)
183 printf("Child process initialized\n");
184 execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]);
185 }
186 //****************************************
187 // start the program using a shell
188 //****************************************
189 else {
190 // choose the shell requested by the user, or use bash as default
191 char *sh;
192 if (cfg.shell)
193 sh = cfg.shell;
194 else if (arg_zsh)
195 sh = "/usr/bin/zsh";
196 else if (arg_csh)
197 sh = "/bin/csh";
198 else
199 sh = "/bin/bash";
200
201 char *arg[5];
202 int index = 0;
203 arg[index++] = sh;
204 arg[index++] = "-c";
205 assert(cfg.command_line);
206 if (arg_debug)
207 printf("Starting %s\n", cfg.command_line);
208 if (arg_doubledash)
209 arg[index++] = "--";
210 arg[index++] = cfg.command_line;
211 arg[index] = NULL;
212 assert(index < 5);
213
214 if (arg_debug) {
215 char *msg;
216 if (asprintf(&msg, "sandbox %d, execvp into %s", sandbox_pid, cfg.command_line) == -1)
217 errExit("asprintf");
218 logmsg(msg);
219 free(msg);
220 }
221
222 if (arg_debug) {
223 int i;
224 for (i = 0; i < 5; i++) {
225 if (arg[i] == NULL)
226 break;
227 printf("execvp argument %d: %s\n", i, arg[i]);
228 }
229 }
230
231 if (!arg_command && !arg_quiet)
232 printf("Child process initialized\n");
233 execvp(sh, arg);
234 }
235
236 perror("execvp");
237 exit(1); // it should never get here!!!
238}
239
240
241
127int sandbox(void* sandbox_arg) { 242int sandbox(void* sandbox_arg) {
128 // Get rid of unused parameter warning 243 // Get rid of unused parameter warning
129 (void)sandbox_arg; 244 (void)sandbox_arg;
@@ -379,7 +494,7 @@ int sandbox(void* sandbox_arg) {
379 fs_delete_cp_command(); 494 fs_delete_cp_command();
380 495
381 //**************************** 496 //****************************
382 // start executable 497 // set application environment
383 //**************************** 498 //****************************
384 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died 499 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died
385 int cwd = 0; 500 int cwd = 0;
@@ -407,6 +522,9 @@ int sandbox(void* sandbox_arg) {
407 // set user-supplied environment variables 522 // set user-supplied environment variables
408 env_apply(); 523 env_apply();
409 524
525 //****************************
526 // set security filters
527 //****************************
410 // set capabilities 528 // set capabilities
411 if (!arg_noroot) 529 if (!arg_noroot)
412 set_caps(); 530 set_caps();
@@ -477,73 +595,18 @@ int sandbox(void* sandbox_arg) {
477 595
478 596
479 //**************************************** 597 //****************************************
480 // start the program without using a shell 598 // fork the application and monitor it
481 //****************************************
482 if (arg_shell_none) {
483 if (arg_debug) {
484 int i;
485 for (i = cfg.original_program_index; i < cfg.original_argc; i++) {
486 if (cfg.original_argv[i] == NULL)
487 break;
488 printf("execvp argument %d: %s\n", i - cfg.original_program_index, cfg.original_argv[i]);
489 }
490 }
491
492 if (!arg_command && !arg_quiet)
493 printf("Child process initialized\n");
494 execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]);
495 }
496 //****************************************
497 // start the program using a shell
498 //**************************************** 599 //****************************************
499 else { 600 pid_t app_pid = fork();
500 // choose the shell requested by the user, or use bash as default 601 if (app_pid == -1)
501 char *sh; 602 errExit("fork");
502 if (cfg.shell)
503 sh = cfg.shell;
504 else if (arg_zsh)
505 sh = "/usr/bin/zsh";
506 else if (arg_csh)
507 sh = "/bin/csh";
508 else
509 sh = "/bin/bash";
510
511 char *arg[5];
512 int index = 0;
513 arg[index++] = sh;
514 arg[index++] = "-c";
515 assert(cfg.command_line);
516 if (arg_debug)
517 printf("Starting %s\n", cfg.command_line);
518 if (arg_doubledash)
519 arg[index++] = "--";
520 arg[index++] = cfg.command_line;
521 arg[index] = NULL;
522 assert(index < 5);
523
524 if (arg_debug) {
525 char *msg;
526 if (asprintf(&msg, "sandbox %d, execvp into %s", sandbox_pid, cfg.command_line) == -1)
527 errExit("asprintf");
528 logmsg(msg);
529 free(msg);
530 }
531 603
532 if (arg_debug) { 604 if (app_pid == 0) {
533 int i; 605 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died
534 for (i = 0; i < 5; i++) { 606 start_application(); // start app
535 if (arg[i] == NULL)
536 break;
537 printf("execvp argument %d: %s\n", i, arg[i]);
538 }
539 }
540
541 if (!arg_command && !arg_quiet)
542 printf("Child process initialized\n");
543 execvp(sh, arg);
544 } 607 }
545
546 608
547 perror("execvp"); 609 monitor_application(app_pid); // monitor application
610
548 return 0; 611 return 0;
549} 612}