aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2016-02-18 20:14:09 -0500
committerLibravatar netblue30 <netblue30@yahoo.com>2016-02-18 20:14:09 -0500
commitefabf8478a426f8f468beea3cfe18e73a849be47 (patch)
treea473dfaa5b3edc5b8fea80b1cf7a3d4004856df0 /src
parentadded mkdir in all whitelisted profiles (diff)
downloadfirejail-efabf8478a426f8f468beea3cfe18e73a849be47.tar.gz
firejail-efabf8478a426f8f468beea3cfe18e73a849be47.tar.zst
firejail-efabf8478a426f8f468beea3cfe18e73a849be47.zip
euid switching
Diffstat (limited to 'src')
-rw-r--r--src/firejail/firejail.h2
-rw-r--r--src/firejail/join.c2
-rw-r--r--src/firejail/list.c12
-rw-r--r--src/firejail/main.c35
-rw-r--r--src/include/euid_common.h48
-rw-r--r--src/lib/common.c1
6 files changed, 92 insertions, 8 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 2662cc1d7..577c1a9ae 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -20,6 +20,8 @@
20#ifndef FIREJAIL_H 20#ifndef FIREJAIL_H
21#define FIREJAIL_H 21#define FIREJAIL_H
22#include "../include/common.h" 22#include "../include/common.h"
23#include "../include/euid_common.h"
24
23 25
24// filesystem 26// filesystem
25#define RUN_FIREJAIL_BASEDIR "/run" 27#define RUN_FIREJAIL_BASEDIR "/run"
diff --git a/src/firejail/join.c b/src/firejail/join.c
index b05e25387..e471e4a21 100644
--- a/src/firejail/join.c
+++ b/src/firejail/join.c
@@ -183,12 +183,12 @@ void join_name(const char *name, const char *homedir, int argc, char **argv, int
183 fprintf(stderr, "Error: invalid sandbox name\n"); 183 fprintf(stderr, "Error: invalid sandbox name\n");
184 exit(1); 184 exit(1);
185 } 185 }
186
186 pid_t pid; 187 pid_t pid;
187 if (name2pid(name, &pid)) { 188 if (name2pid(name, &pid)) {
188 fprintf(stderr, "Error: cannot find sandbox %s\n", name); 189 fprintf(stderr, "Error: cannot find sandbox %s\n", name);
189 exit(1); 190 exit(1);
190 } 191 }
191
192 join(pid, homedir, argc, argv, index); 192 join(pid, homedir, argc, argv, index);
193} 193}
194 194
diff --git a/src/firejail/list.c b/src/firejail/list.c
index 7a3cf0aad..d5ef1ac2c 100644
--- a/src/firejail/list.c
+++ b/src/firejail/list.c
@@ -20,7 +20,8 @@
20#include "firejail.h" 20#include "firejail.h"
21 21
22void top(void) { 22void top(void) {
23 drop_privs(1); 23 if (getuid() != geteuid())
24 drop_privs(1);
24 25
25 char *arg[4]; 26 char *arg[4];
26 arg[0] = "bash"; 27 arg[0] = "bash";
@@ -31,7 +32,8 @@ void top(void) {
31} 32}
32 33
33void netstats(void) { 34void netstats(void) {
34 drop_privs(1); 35 if (getuid() != geteuid())
36 drop_privs(1);
35 37
36 char *arg[4]; 38 char *arg[4];
37 arg[0] = "bash"; 39 arg[0] = "bash";
@@ -42,7 +44,8 @@ void netstats(void) {
42} 44}
43 45
44void list(void) { 46void list(void) {
45 drop_privs(1); 47 if (getuid() != geteuid())
48 drop_privs(1);
46 49
47 char *arg[4]; 50 char *arg[4];
48 arg[0] = "bash"; 51 arg[0] = "bash";
@@ -53,7 +56,8 @@ void list(void) {
53} 56}
54 57
55void tree(void) { 58void tree(void) {
56 drop_privs(1); 59 if (getuid() != geteuid())
60 drop_privs(1);
57 61
58 char *arg[4]; 62 char *arg[4];
59 arg[0] = "bash"; 63 arg[0] = "bash";
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 6fd011868..688653ce2 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -45,6 +45,8 @@ printf("time %s:%d %u\n", __FILE__, __LINE__, (uint32_t) systick);
45} 45}
46#endif 46#endif
47 47
48uid_t firejail_uid = 0;
49
48#define STACK_SIZE (1024 * 1024) 50#define STACK_SIZE (1024 * 1024)
49static char child_stack[STACK_SIZE]; // space for child's stack 51static char child_stack[STACK_SIZE]; // space for child's stack
50Config cfg; // configuration 52Config cfg; // configuration
@@ -124,11 +126,13 @@ static void my_handler(int s){
124 126
125static void extract_user_data(void) { 127static void extract_user_data(void) {
126 // check suid 128 // check suid
129 EUID_ROOT();
127 if (geteuid()) { 130 if (geteuid()) {
128 fprintf(stderr, "Error: the sandbox is not setuid root\n"); 131 fprintf(stderr, "Error: the sandbox is not setuid root\n");
129 exit(1); 132 exit(1);
130 } 133 }
131 134 EUID_USER();
135
132 struct passwd *pw = getpwuid(getuid()); 136 struct passwd *pw = getpwuid(getuid());
133 if (!pw) 137 if (!pw)
134 errExit("getpwuid"); 138 errExit("getpwuid");
@@ -315,6 +319,7 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
315 319
316 // extract pid or sandbox name 320 // extract pid or sandbox name
317 pid_t pid; 321 pid_t pid;
322 EUID_ROOT();
318 if (read_pid(argv[i] + 12, &pid) == 0) 323 if (read_pid(argv[i] + 12, &pid) == 0)
319 bandwidth_pid(pid, cmd, dev, down, up); 324 bandwidth_pid(pid, cmd, dev, down, up);
320 else 325 else
@@ -337,6 +342,7 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
337 else if (strncmp(argv[i], "--seccomp.print=", 16) == 0) { 342 else if (strncmp(argv[i], "--seccomp.print=", 16) == 0) {
338 // print seccomp filter for a sandbox specified by pid or by name 343 // print seccomp filter for a sandbox specified by pid or by name
339 pid_t pid; 344 pid_t pid;
345 EUID_ROOT();
340 if (read_pid(argv[i] + 16, &pid) == 0) 346 if (read_pid(argv[i] + 16, &pid) == 0)
341 seccomp_print_filter(pid); 347 seccomp_print_filter(pid);
342 else 348 else
@@ -350,6 +356,7 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
350 else if (strncmp(argv[i], "--protocol.print=", 17) == 0) { 356 else if (strncmp(argv[i], "--protocol.print=", 17) == 0) {
351 // print seccomp filter for a sandbox specified by pid or by name 357 // print seccomp filter for a sandbox specified by pid or by name
352 pid_t pid; 358 pid_t pid;
359 EUID_ROOT();
353 if (read_pid(argv[i] + 17, &pid) == 0) 360 if (read_pid(argv[i] + 17, &pid) == 0)
354 protocol_print_filter(pid); 361 protocol_print_filter(pid);
355 else 362 else
@@ -360,6 +367,7 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
360 else if (strncmp(argv[i], "--caps.print=", 13) == 0) { 367 else if (strncmp(argv[i], "--caps.print=", 13) == 0) {
361 // join sandbox by pid or by name 368 // join sandbox by pid or by name
362 pid_t pid; 369 pid_t pid;
370 EUID_ROOT();
363 if (read_pid(argv[i] + 13, &pid) == 0) 371 if (read_pid(argv[i] + 13, &pid) == 0)
364 caps_print_filter(pid); 372 caps_print_filter(pid);
365 else 373 else
@@ -369,6 +377,7 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
369 else if (strncmp(argv[i], "--fs.print=", 11) == 0) { 377 else if (strncmp(argv[i], "--fs.print=", 11) == 0) {
370 // join sandbox by pid or by name 378 // join sandbox by pid or by name
371 pid_t pid; 379 pid_t pid;
380 EUID_ROOT();
372 if (read_pid(argv[i] + 11, &pid) == 0) 381 if (read_pid(argv[i] + 11, &pid) == 0)
373 fs_logger_print_log(pid); 382 fs_logger_print_log(pid);
374 else 383 else
@@ -378,6 +387,7 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
378 else if (strncmp(argv[i], "--dns.print=", 12) == 0) { 387 else if (strncmp(argv[i], "--dns.print=", 12) == 0) {
379 // join sandbox by pid or by name 388 // join sandbox by pid or by name
380 pid_t pid; 389 pid_t pid;
390 EUID_ROOT();
381 if (read_pid(argv[i] + 12, &pid) == 0) 391 if (read_pid(argv[i] + 12, &pid) == 0)
382 net_dns_print(pid); 392 net_dns_print(pid);
383 else 393 else
@@ -411,6 +421,7 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
411 421
412 // join sandbox by pid or by name 422 // join sandbox by pid or by name
413 pid_t pid; 423 pid_t pid;
424 EUID_ROOT();
414 if (read_pid(argv[i] + 7, &pid) == 0) 425 if (read_pid(argv[i] + 7, &pid) == 0)
415 join(pid, cfg.homedir, argc, argv, i + 1); 426 join(pid, cfg.homedir, argc, argv, i + 1);
416 else 427 else
@@ -456,6 +467,7 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
456 467
457 // shutdown sandbox by pid or by name 468 // shutdown sandbox by pid or by name
458 pid_t pid; 469 pid_t pid;
470 EUID_ROOT();
459 if (read_pid(argv[i] + 11, &pid) == 0) 471 if (read_pid(argv[i] + 11, &pid) == 0)
460 shut(pid); 472 shut(pid);
461 else 473 else
@@ -480,6 +492,10 @@ int main(int argc, char **argv) {
480#ifdef HAVE_SECCOMP 492#ifdef HAVE_SECCOMP
481 int highest_errno = errno_highest_nr(); 493 int highest_errno = errno_highest_nr();
482#endif 494#endif
495
496 // drop permissions by default and rise them when required
497 EUID_INIT();
498 EUID_USER();
483 499
484 // check argv[0] symlink wrapper if this is not a login shell 500 // check argv[0] symlink wrapper if this is not a login shell
485 if (*argv[0] != '-') 501 if (*argv[0] != '-')
@@ -517,10 +533,12 @@ int main(int argc, char **argv) {
517 srand(t ^ sandbox_pid); 533 srand(t ^ sandbox_pid);
518 534
519 // check firejail directories 535 // check firejail directories
536 EUID_ROOT();
520 fs_build_firejail_dir(); 537 fs_build_firejail_dir();
521 shm_create_firejail_dir(); 538 shm_create_firejail_dir();
522 bandwidth_shm_del_file(sandbox_pid); 539 bandwidth_shm_del_file(sandbox_pid);
523 540 EUID_USER();
541
524 // is this a login shell? 542 // is this a login shell?
525 if (*argv[0] == '-') { 543 if (*argv[0] == '-') {
526 fullargc = restricted_shell(cfg.username); 544 fullargc = restricted_shell(cfg.username);
@@ -1449,6 +1467,7 @@ int main(int argc, char **argv) {
1449 1467
1450 // check and assign an IP address - for macvlan it will be done again in the sandbox! 1468 // check and assign an IP address - for macvlan it will be done again in the sandbox!
1451 if (any_bridge_configured()) { 1469 if (any_bridge_configured()) {
1470 EUID_ROOT();
1452 lockfd = open(RUN_NETWORK_LOCK_FILE, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); 1471 lockfd = open(RUN_NETWORK_LOCK_FILE, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
1453 if (lockfd != -1) { 1472 if (lockfd != -1) {
1454 int rv = fchown(lockfd, 0, 0); 1473 int rv = fchown(lockfd, 0, 0);
@@ -1463,6 +1482,7 @@ int main(int argc, char **argv) {
1463 1482
1464 // save network mapping in shared memory 1483 // save network mapping in shared memory
1465 network_shm_set_file(sandbox_pid); 1484 network_shm_set_file(sandbox_pid);
1485 EUID_USER();
1466 } 1486 }
1467 1487
1468 // create the parent-child communication pipe 1488 // create the parent-child communication pipe
@@ -1494,12 +1514,14 @@ int main(int argc, char **argv) {
1494 else if (arg_debug) 1514 else if (arg_debug)
1495 printf("Using the local network stack\n"); 1515 printf("Using the local network stack\n");
1496 1516
1517 EUID_ROOT();
1497 child = clone(sandbox, 1518 child = clone(sandbox,
1498 child_stack + STACK_SIZE, 1519 child_stack + STACK_SIZE,
1499 flags, 1520 flags,
1500 NULL); 1521 NULL);
1501 if (child == -1) 1522 if (child == -1)
1502 errExit("clone"); 1523 errExit("clone");
1524 EUID_USER();
1503 1525
1504 if (!arg_command && !arg_quiet) { 1526 if (!arg_command && !arg_quiet) {
1505 printf("Parent pid %u, child pid %u\n", sandbox_pid, child); 1527 printf("Parent pid %u, child pid %u\n", sandbox_pid, child);
@@ -1508,7 +1530,8 @@ int main(int argc, char **argv) {
1508 printf("The new log directory is /proc/%d/root/var/log\n", child); 1530 printf("The new log directory is /proc/%d/root/var/log\n", child);
1509 } 1531 }
1510 1532
1511 1533
1534 EUID_ROOT();
1512 if (!arg_nonetwork) { 1535 if (!arg_nonetwork) {
1513 // create veth pair or macvlan device 1536 // create veth pair or macvlan device
1514 if (cfg.bridge0.configured) { 1537 if (cfg.bridge0.configured) {
@@ -1554,6 +1577,7 @@ int main(int argc, char **argv) {
1554 net_move_interface(cfg.interface3.dev, child); 1577 net_move_interface(cfg.interface3.dev, child);
1555 } 1578 }
1556 } 1579 }
1580 EUID_USER();
1557 1581
1558 // close each end of the unused pipes 1582 // close each end of the unused pipes
1559 close(parent_to_child_fds[0]); 1583 close(parent_to_child_fds[0]);
@@ -1576,7 +1600,9 @@ int main(int argc, char **argv) {
1576 uid_t uid = getuid(); 1600 uid_t uid = getuid();
1577 if (asprintf(&map, "%d %d 1", uid, uid) == -1) 1601 if (asprintf(&map, "%d %d 1", uid, uid) == -1)
1578 errExit("asprintf"); 1602 errExit("asprintf");
1603 EUID_ROOT();
1579 update_map(map, map_path); 1604 update_map(map, map_path);
1605 EUID_USER();
1580 free(map); 1606 free(map);
1581 free(map_path); 1607 free(map_path);
1582 1608
@@ -1586,7 +1612,9 @@ int main(int argc, char **argv) {
1586 gid_t gid = getgid(); 1612 gid_t gid = getgid();
1587 if (asprintf(&map, "%d %d 1", gid, gid) == -1) 1613 if (asprintf(&map, "%d %d 1", gid, gid) == -1)
1588 errExit("asprintf"); 1614 errExit("asprintf");
1615 EUID_ROOT();
1589 update_map(map, map_path); 1616 update_map(map, map_path);
1617 EUID_USER();
1590 free(map); 1618 free(map);
1591 free(map_path); 1619 free(map_path);
1592 } 1620 }
@@ -1595,6 +1623,7 @@ int main(int argc, char **argv) {
1595 notify_other(parent_to_child_fds[1]); 1623 notify_other(parent_to_child_fds[1]);
1596 close(parent_to_child_fds[1]); 1624 close(parent_to_child_fds[1]);
1597 1625
1626 EUID_ROOT();
1598 if (lockfd != -1) 1627 if (lockfd != -1)
1599 flock(lockfd, LOCK_UN); 1628 flock(lockfd, LOCK_UN);
1600 1629
diff --git a/src/include/euid_common.h b/src/include/euid_common.h
new file mode 100644
index 000000000..1cba548ab
--- /dev/null
+++ b/src/include/euid_common.h
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2014-2016 netblue30 (netblue30@yahoo.com)
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20
21#ifndef EUID_COMMON_H
22#define EUID_COMMON_H
23#include <stdio.h>
24#include <sys/types.h>
25#include <unistd.h>
26
27extern uid_t firejail_uid;
28extern uid_t firejail_uid_switch;
29
30static inline void EUID_ROOT(void) {
31 if (seteuid(0) == -1)
32 fprintf(stderr, "Error: cannot switch euid to root\n");
33}
34
35static inline void EUID_USER(void) {
36 if (seteuid(firejail_uid) == -1)
37 fprintf(stderr, "Error: cannot switch euid to user\n");
38}
39
40static inline void EUID_PRINT(void) {
41 printf("debug: uid %d, euid %d\n", getuid(), geteuid());
42}
43
44static inline void EUID_INIT(void) {
45 firejail_uid = getuid();
46}
47
48#endif
diff --git a/src/lib/common.c b/src/lib/common.c
index d23cd589e..099bb54d3 100644
--- a/src/lib/common.c
+++ b/src/lib/common.c
@@ -58,6 +58,7 @@ int join_namespace(pid_t pid, char *type) {
58} 58}
59 59
60// return 1 if error 60// return 1 if error
61// this function requires root access - todo: fix it!
61int name2pid(const char *name, pid_t *pid) { 62int name2pid(const char *name, pid_t *pid) {
62 pid_t parent = getpid(); 63 pid_t parent = getpid();
63 64