aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail
diff options
context:
space:
mode:
Diffstat (limited to 'src/firejail')
-rw-r--r--src/firejail/firejail.h2
-rw-r--r--src/firejail/main.c10
-rw-r--r--src/firejail/netfilter.c55
-rw-r--r--src/firejail/network_main.c7
-rw-r--r--src/firejail/usage.c1
-rw-r--r--src/firejail/util.c38
6 files changed, 60 insertions, 53 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 2d96863c5..7f6ed2586 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -416,6 +416,7 @@ void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child);
416void net_check_cfg(void); 416void net_check_cfg(void);
417void net_dns_print(pid_t pid); 417void net_dns_print(pid_t pid);
418void network_main(pid_t child); 418void network_main(pid_t child);
419void net_print(pid_t pid);
419 420
420// network.c 421// network.c
421int check_ip46_address(const char *addr); 422int check_ip46_address(const char *addr);
@@ -547,6 +548,7 @@ void disable_file_or_dir(const char *fname);
547void disable_file_path(const char *path, const char *file); 548void disable_file_path(const char *path, const char *file);
548int safe_fd(const char *path, int flags); 549int safe_fd(const char *path, int flags);
549int invalid_sandbox(const pid_t pid); 550int invalid_sandbox(const pid_t pid);
551void enter_network_namespace(pid_t pid);
550 552
551// Get info regarding the last kernel mount operation from /proc/self/mountinfo 553// Get info regarding the last kernel mount operation from /proc/self/mountinfo
552// The return value points to a static area, and will be overwritten by subsequent calls. 554// The return value points to a static area, and will be overwritten by subsequent calls.
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 29e3df7c6..23d9a1d51 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -592,6 +592,16 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
592 else 592 else
593 exit_err_feature("networking"); 593 exit_err_feature("networking");
594 } 594 }
595 else if (strncmp(argv[i], "--net.print=", 12) == 0) {
596 if (checkcfg(CFG_NETWORK)) {
597 // extract pid or sandbox name
598 pid_t pid = require_pid(argv[i] + 12);
599 net_print(pid);
600 exit(0);
601 }
602 else
603 exit_err_feature("networking");
604 }
595#endif 605#endif
596#ifdef HAVE_FILE_TRANSFER 606#ifdef HAVE_FILE_TRANSFER
597 else if (strncmp(argv[i], "--get=", 6) == 0) { 607 else if (strncmp(argv[i], "--get=", 6) == 0) {
diff --git a/src/firejail/netfilter.c b/src/firejail/netfilter.c
index 8fbd11bba..ed2d019ab 100644
--- a/src/firejail/netfilter.c
+++ b/src/firejail/netfilter.c
@@ -132,63 +132,12 @@ void netfilter6(const char *fname) {
132void netfilter_print(pid_t pid, int ipv6) { 132void netfilter_print(pid_t pid, int ipv6) {
133 EUID_ASSERT(); 133 EUID_ASSERT();
134 134
135 // verify sandbox 135 enter_network_namespace(pid);
136 EUID_ROOT();
137 char *comm = pid_proc_comm(pid);
138 EUID_USER();
139 if (!comm) {
140 fprintf(stderr, "Error: cannot find sandbox\n");
141 exit(1);
142 }
143
144 // check for firejail sandbox
145 if (strcmp(comm, "firejail") != 0) {
146 fprintf(stderr, "Error: cannot find sandbox\n");
147 exit(1);
148 }
149 free(comm);
150
151 // check privileges for non-root users
152 uid_t uid = getuid();
153 if (uid != 0) {
154 uid_t sandbox_uid = pid_get_uid(pid);
155 if (uid != sandbox_uid) {
156 fprintf(stderr, "Error: permission is denied to join a sandbox created by a different user.\n");
157 exit(1);
158 }
159 }
160
161 // check network namespace
162 char *name;
163 if (asprintf(&name, "/run/firejail/network/%d-netmap", pid) == -1)
164 errExit("asprintf");
165 struct stat s;
166 if (stat(name, &s) == -1) {
167 fprintf(stderr, "Error: the sandbox doesn't use a new network namespace\n");
168 exit(1);
169 }
170
171 // join the network namespace
172 pid_t child;
173 if (find_child(pid, &child) == 1) {
174 fprintf(stderr, "Error: cannot join the network namespace\n");
175 exit(1);
176 }
177
178 if (invalid_sandbox(child)) {
179 fprintf(stderr, "Error: cannot join the network namespace\n");
180 exit(1);
181 }
182
183 EUID_ROOT();
184 if (join_namespace(child, "net")) {
185 fprintf(stderr, "Error: cannot join the network namespace\n");
186 exit(1);
187 }
188 136
189 // find iptables executable 137 // find iptables executable
190 char *iptables = NULL; 138 char *iptables = NULL;
191// char *iptables_restore = NULL; 139// char *iptables_restore = NULL;
140 struct stat s;
192 if (ipv6) { 141 if (ipv6) {
193 if (stat("/sbin/ip6tables", &s) == 0) 142 if (stat("/sbin/ip6tables", &s) == 0)
194 iptables = "/sbin/ip6tables"; 143 iptables = "/sbin/ip6tables";
diff --git a/src/firejail/network_main.c b/src/firejail/network_main.c
index cdb4c6514..4dee07219 100644
--- a/src/firejail/network_main.c
+++ b/src/firejail/network_main.c
@@ -372,3 +372,10 @@ void network_main(pid_t child) {
372 372
373 free(cstr); 373 free(cstr);
374} 374}
375
376void net_print(pid_t pid) {
377 EUID_ASSERT();
378
379 enter_network_namespace(pid);
380 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, PATH_FNET_MAIN, "printif");
381} \ No newline at end of file
diff --git a/src/firejail/usage.c b/src/firejail/usage.c
index b8f8b4f2f..84bc22571 100644
--- a/src/firejail/usage.c
+++ b/src/firejail/usage.c
@@ -115,6 +115,7 @@ static char *usage_str =
115 " --net=ethernet_interface - enable network namespaces and connect to this\n" 115 " --net=ethernet_interface - enable network namespaces and connect to this\n"
116 "\tEthernet interface.\n" 116 "\tEthernet interface.\n"
117 " --net=none - enable a new, unconnected network namespace.\n" 117 " --net=none - enable a new, unconnected network namespace.\n"
118 " --net.print=name|pid - print network interface configuration.\n"
118 " --netfilter[=filename,arg1,arg2,arg3 ...] - enable firewall.\n" 119 " --netfilter[=filename,arg1,arg2,arg3 ...] - enable firewall.\n"
119 " --netfilter.print=name|pid - print the firewall.\n" 120 " --netfilter.print=name|pid - print the firewall.\n"
120 " --netfilter6=filename - enable IPv6 firewall.\n" 121 " --netfilter6=filename - enable IPv6 firewall.\n"
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 866ef4653..47b237911 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -1225,3 +1225,41 @@ int invalid_sandbox(const pid_t pid) {
1225 1225
1226 return 0; 1226 return 0;
1227} 1227}
1228
1229void enter_network_namespace(pid_t pid) {
1230 // in case the pid is that of a firejail process, use the pid of the first child process
1231 pid_t child = switch_to_child(pid);
1232
1233 // now check if the pid belongs to a firejail sandbox
1234 if (invalid_sandbox(child)) {
1235 fprintf(stderr, "Error: no valid sandbox\n");
1236 exit(1);
1237 }
1238
1239 // check privileges for non-root users
1240 uid_t uid = getuid();
1241 if (uid != 0) {
1242 uid_t sandbox_uid = pid_get_uid(pid);
1243 if (uid != sandbox_uid) {
1244 fprintf(stderr, "Error: permission is denied to join a sandbox created by a different user.\n");
1245 exit(1);
1246 }
1247 }
1248
1249 // check network namespace
1250 char *name;
1251 if (asprintf(&name, "/run/firejail/network/%d-netmap", pid) == -1)
1252 errExit("asprintf");
1253 struct stat s;
1254 if (stat(name, &s) == -1) {
1255 fprintf(stderr, "Error: the sandbox doesn't use a new network namespace\n");
1256 exit(1);
1257 }
1258
1259 // join the namespace
1260 EUID_ROOT();
1261 if (join_namespace(child, "net")) {
1262 fprintf(stderr, "Error: cannot join the network namespace\n");
1263 exit(1);
1264 }
1265} \ No newline at end of file