aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2016-11-29 21:38:09 -0500
committerLibravatar netblue30 <netblue30@yahoo.com>2016-11-29 21:38:09 -0500
commit84fa03cd77b0afcdee5cc6816596ab5c8a633185 (patch)
tree97b0ef919fbe2a32cbfcf61ccad86cc20ef41ce4 /src
parenttesting (diff)
downloadfirejail-84fa03cd77b0afcdee5cc6816596ab5c8a633185.tar.gz
firejail-84fa03cd77b0afcdee5cc6816596ab5c8a633185.tar.zst
firejail-84fa03cd77b0afcdee5cc6816596ab5c8a633185.zip
private-opt and private-srv
Diffstat (limited to 'src')
-rw-r--r--src/firejail/firejail.h8
-rw-r--r--src/firejail/fs_etc.c34
-rw-r--r--src/firejail/main.c20
-rw-r--r--src/firejail/profile.c16
-rw-r--r--src/firejail/sandbox.c22
5 files changed, 83 insertions, 17 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 61de17bf8..d172efce1 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -43,6 +43,8 @@
43#define RUN_PROTOCOL_CFG "/run/firejail/mnt/protocol" 43#define RUN_PROTOCOL_CFG "/run/firejail/mnt/protocol"
44#define RUN_HOME_DIR "/run/firejail/mnt/home" 44#define RUN_HOME_DIR "/run/firejail/mnt/home"
45#define RUN_ETC_DIR "/run/firejail/mnt/etc" 45#define RUN_ETC_DIR "/run/firejail/mnt/etc"
46#define RUN_OPT_DIR "/run/firejail/mnt/opt"
47#define RUN_SRV_DIR "/run/firejail/mnt/srv"
46#define RUN_BIN_DIR "/run/firejail/mnt/bin" 48#define RUN_BIN_DIR "/run/firejail/mnt/bin"
47#define RUN_PULSE_DIR "/run/firejail/mnt/pulse" 49#define RUN_PULSE_DIR "/run/firejail/mnt/pulse"
48 50
@@ -200,6 +202,8 @@ typedef struct config_t {
200 char *home_private; // private home directory 202 char *home_private; // private home directory
201 char *home_private_keep; // keep list for private home directory 203 char *home_private_keep; // keep list for private home directory
202 char *etc_private_keep; // keep list for private etc directory 204 char *etc_private_keep; // keep list for private etc directory
205 char *opt_private_keep; // keep list for private opt directory
206 char *srv_private_keep; // keep list for private srv directory
203 char *bin_private_keep; // keep list for private bin directory 207 char *bin_private_keep; // keep list for private bin directory
204 char *cwd; // current working directory 208 char *cwd; // current working directory
205 char *overlay_dir; 209 char *overlay_dir;
@@ -315,6 +319,8 @@ extern int arg_doubledash; // double dash
315extern int arg_shell_none; // run the program directly without a shell 319extern int arg_shell_none; // run the program directly without a shell
316extern int arg_private_dev; // private dev directory 320extern int arg_private_dev; // private dev directory
317extern int arg_private_etc; // private etc directory 321extern int arg_private_etc; // private etc directory
322extern int arg_private_opt; // private opt directory
323extern int arg_private_srv; // private srv directory
318extern int arg_private_bin; // private bin directory 324extern int arg_private_bin; // private bin directory
319extern int arg_private_tmp; // private tmp directory 325extern int arg_private_tmp; // private tmp directory
320extern int arg_scan; // arp-scan all interfaces 326extern int arg_scan; // arp-scan all interfaces
@@ -556,7 +562,7 @@ void network_del_run_file(pid_t pid);
556void network_set_run_file(pid_t pid); 562void network_set_run_file(pid_t pid);
557 563
558// fs_etc.c 564// fs_etc.c
559void fs_private_etc_list(void); 565void fs_private_dir_list(const char *private_dir, const char *private_run_dir, const char *private_list);
560 566
561// no_sandbox.c 567// no_sandbox.c
562int check_namespace_virt(void); 568int check_namespace_virt(void);
diff --git a/src/firejail/fs_etc.c b/src/firejail/fs_etc.c
index 80329d5ba..9a28ac601 100644
--- a/src/firejail/fs_etc.c
+++ b/src/firejail/fs_etc.c
@@ -47,7 +47,7 @@ errexit:
47 exit(1); 47 exit(1);
48} 48}
49 49
50static void duplicate(char *fname) { 50static void duplicate(const char *fname, const char *private_dir, const char *private_run_dir) {
51 if (*fname == '~' || *fname == '/' || strstr(fname, "..")) { 51 if (*fname == '~' || *fname == '/' || strstr(fname, "..")) {
52 fprintf(stderr, "Error: \"%s\" is an invalid filename\n", fname); 52 fprintf(stderr, "Error: \"%s\" is an invalid filename\n", fname);
53 exit(1); 53 exit(1);
@@ -55,40 +55,44 @@ static void duplicate(char *fname) {
55 invalid_filename(fname); 55 invalid_filename(fname);
56 56
57 char *src; 57 char *src;
58 if (asprintf(&src, "/etc/%s", fname) == -1) 58 if (asprintf(&src, "%s/%s", private_dir, fname) == -1)
59 errExit("asprintf"); 59 errExit("asprintf");
60 if (check_dir_or_file(src) == 0) { 60 if (check_dir_or_file(src) == 0) {
61 if (!arg_quiet) 61 if (!arg_quiet)
62 fprintf(stderr, "Warning: skipping %s for private bin\n", fname); 62 fprintf(stderr, "Warning: skipping %s for private %s\n", fname, private_dir);
63 free(src); 63 free(src);
64 return; 64 return;
65 } 65 }
66 66
67 if (arg_debug)
68 printf("copying %s to private %s\n", src, private_dir);
69
67 struct stat s; 70 struct stat s;
68 if (stat(src, &s) == 0 && S_ISDIR(s.st_mode)) { 71 if (stat(src, &s) == 0 && S_ISDIR(s.st_mode)) {
69 // create the directory in RUN_ETC_DIR 72 // create the directory in RUN_ETC_DIR
70 char *dirname; 73 char *dirname;
71 if (asprintf(&dirname, "%s/%s", RUN_ETC_DIR, fname) == -1) 74 if (asprintf(&dirname, "%s/%s", private_run_dir, fname) == -1)
72 errExit("asprintf"); 75 errExit("asprintf");
73 create_empty_dir_as_root(dirname, s.st_mode); 76 create_empty_dir_as_root(dirname, s.st_mode);
74 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, src, dirname); 77 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, src, dirname);
75 free(dirname); 78 free(dirname);
76 } 79 }
77 else 80 else
78 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, src, RUN_ETC_DIR); 81 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, src, private_run_dir);
79 82
80 fs_logger2("clone", src); 83 fs_logger2("clone", src);
81 free(src); 84 free(src);
82} 85}
83 86
84 87
85void fs_private_etc_list(void) { 88void fs_private_dir_list(const char *private_dir, const char *private_run_dir, const char *private_list) {
86 char *private_list = cfg.etc_private_keep; 89 assert(private_dir);
90 assert(private_run_dir);
87 assert(private_list); 91 assert(private_list);
88 92
89 // create /run/firejail/mnt/etc directory 93 // create /run/firejail/mnt/etc directory
90 mkdir_attr(RUN_ETC_DIR, 0755, 0, 0); 94 mkdir_attr(private_run_dir, 0755, 0, 0);
91 fs_logger("tmpfs /etc"); 95 fs_logger2("tmpfs", private_dir);
92 96
93 fs_logger_print(); // save the current log 97 fs_logger_print(); // save the current log
94 98
@@ -97,7 +101,7 @@ void fs_private_etc_list(void) {
97 // using a new child process with root privileges 101 // using a new child process with root privileges
98 if (*private_list != '\0') { 102 if (*private_list != '\0') {
99 if (arg_debug) 103 if (arg_debug)
100 printf("Copying files in the new etc directory:\n"); 104 printf("Copying files in the new %s directory:\n", private_dir);
101 105
102 // copy the list of files in the new home directory 106 // copy the list of files in the new home directory
103 char *dlist = strdup(private_list); 107 char *dlist = strdup(private_list);
@@ -106,18 +110,18 @@ void fs_private_etc_list(void) {
106 110
107 111
108 char *ptr = strtok(dlist, ","); 112 char *ptr = strtok(dlist, ",");
109 duplicate(ptr); 113 duplicate(ptr, private_dir, private_run_dir);
110 114
111 while ((ptr = strtok(NULL, ",")) != NULL) 115 while ((ptr = strtok(NULL, ",")) != NULL)
112 duplicate(ptr); 116 duplicate(ptr, private_dir, private_run_dir);
113 free(dlist); 117 free(dlist);
114 fs_logger_print(); 118 fs_logger_print();
115 } 119 }
116 120
117 if (arg_debug) 121 if (arg_debug)
118 printf("Mount-bind %s on top of /etc\n", RUN_ETC_DIR); 122 printf("Mount-bind %s on top of %s\n", private_run_dir, private_dir);
119 if (mount(RUN_ETC_DIR, "/etc", NULL, MS_BIND|MS_REC, NULL) < 0) 123 if (mount(private_run_dir, private_dir, NULL, MS_BIND|MS_REC, NULL) < 0)
120 errExit("mount bind"); 124 errExit("mount bind");
121 fs_logger("mount /etc"); 125 fs_logger2("mount", private_dir);
122} 126}
123 127
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 0929347b7..4ccbb6a86 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -88,6 +88,8 @@ int arg_doubledash = 0; // double dash
88int arg_shell_none = 0; // run the program directly without a shell 88int arg_shell_none = 0; // run the program directly without a shell
89int arg_private_dev = 0; // private dev directory 89int arg_private_dev = 0; // private dev directory
90int arg_private_etc = 0; // private etc directory 90int arg_private_etc = 0; // private etc directory
91int arg_private_opt = 0; // private opt directory
92int arg_private_srv = 0; // private srv directory
91int arg_private_bin = 0; // private bin directory 93int arg_private_bin = 0; // private bin directory
92int arg_private_tmp = 0; // private tmp directory 94int arg_private_tmp = 0; // private tmp directory
93int arg_scan = 0; // arp-scan all interfaces 95int arg_scan = 0; // arp-scan all interfaces
@@ -1624,6 +1626,24 @@ int main(int argc, char **argv) {
1624 } 1626 }
1625 arg_private_etc = 1; 1627 arg_private_etc = 1;
1626 } 1628 }
1629 else if (strncmp(argv[i], "--private-opt=", 14) == 0) {
1630 // extract private opt list
1631 cfg.opt_private_keep = argv[i] + 14;
1632 if (*cfg.opt_private_keep == '\0') {
1633 fprintf(stderr, "Error: invalid private-opt option\n");
1634 exit(1);
1635 }
1636 arg_private_opt = 1;
1637 }
1638 else if (strncmp(argv[i], "--private-srv=", 14) == 0) {
1639 // extract private srv list
1640 cfg.srv_private_keep = argv[i] + 14;
1641 if (*cfg.srv_private_keep == '\0') {
1642 fprintf(stderr, "Error: invalid private-etc option\n");
1643 exit(1);
1644 }
1645 arg_private_srv = 1;
1646 }
1627 else if (strncmp(argv[i], "--private-bin=", 14) == 0) { 1647 else if (strncmp(argv[i], "--private-bin=", 14) == 0) {
1628 // extract private bin list 1648 // extract private bin list
1629 cfg.bin_private_keep = argv[i] + 14; 1649 cfg.bin_private_keep = argv[i] + 14;
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 9acb1b813..2be6948f0 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -739,6 +739,22 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
739 return 0; 739 return 0;
740 } 740 }
741 741
742 // private /opt list of files and directories
743 if (strncmp(ptr, "private-opt ", 12) == 0) {
744 cfg.opt_private_keep = ptr + 12;
745 arg_private_opt = 1;
746
747 return 0;
748 }
749
750 // private /srv list of files and directories
751 if (strncmp(ptr, "private-srv ", 12) == 0) {
752 cfg.srv_private_keep = ptr + 12;
753 arg_private_srv = 1;
754
755 return 0;
756 }
757
742 // private /bin list of files 758 // private /bin list of files
743 if (strncmp(ptr, "private-bin ", 12) == 0) { 759 if (strncmp(ptr, "private-bin ", 12) == 0) {
744 cfg.bin_private_keep = ptr + 12; 760 cfg.bin_private_keep = ptr + 12;
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 0a6777fef..68b8f554d 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -671,13 +671,33 @@ int sandbox(void* sandbox_arg) {
671 else if (arg_overlay) 671 else if (arg_overlay)
672 fprintf(stderr, "Warning: private-etc feature is disabled in overlay\n"); 672 fprintf(stderr, "Warning: private-etc feature is disabled in overlay\n");
673 else { 673 else {
674 fs_private_etc_list(); 674 fs_private_dir_list("/etc", RUN_ETC_DIR, cfg.etc_private_keep);
675 // create /etc/ld.so.preload file again 675 // create /etc/ld.so.preload file again
676 if (arg_trace || arg_tracelog || mask_x11_abstract_socket) 676 if (arg_trace || arg_tracelog || mask_x11_abstract_socket)
677 fs_trace_preload(); 677 fs_trace_preload();
678 } 678 }
679 } 679 }
680 680
681 if (arg_private_opt) {
682 if (cfg.chrootdir)
683 fprintf(stderr, "Warning: private-opt feature is disabled in chroot\n");
684 else if (arg_overlay)
685 fprintf(stderr, "Warning: private-opt feature is disabled in overlay\n");
686 else {
687 fs_private_dir_list("/opt", RUN_OPT_DIR, cfg.opt_private_keep);
688 }
689 }
690
691 if (arg_private_srv) {
692 if (cfg.chrootdir)
693 fprintf(stderr, "Warning: private-srv feature is disabled in chroot\n");
694 else if (arg_overlay)
695 fprintf(stderr, "Warning: private-srv feature is disabled in overlay\n");
696 else {
697 fs_private_dir_list("/srv", RUN_SRV_DIR, cfg.srv_private_keep);
698 }
699 }
700
681 if (arg_private_bin) { 701 if (arg_private_bin) {
682 if (cfg.chrootdir) 702 if (cfg.chrootdir)
683 fprintf(stderr, "Warning: private-bin feature is disabled in chroot\n"); 703 fprintf(stderr, "Warning: private-bin feature is disabled in chroot\n");