diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/firecfg/firecfg.config | 1 | ||||
-rw-r--r-- | src/firejail/firejail.h | 1 | ||||
-rw-r--r-- | src/firejail/fs_dev.c | 5 | ||||
-rw-r--r-- | src/firejail/join.c | 54 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 34 | ||||
-rw-r--r-- | src/firejail/sbox.c | 13 |
6 files changed, 84 insertions, 24 deletions
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config index adf66f008..4cd4fad6c 100644 --- a/src/firecfg/firecfg.config +++ b/src/firecfg/firecfg.config | |||
@@ -722,6 +722,7 @@ xmr-stak | |||
722 | xonotic | 722 | xonotic |
723 | xonotic-glx | 723 | xonotic-glx |
724 | xonotic-sdl | 724 | xonotic-sdl |
725 | xournal | ||
725 | xpdf | 726 | xpdf |
726 | xplayer | 727 | xplayer |
727 | xplayer-audio-preview | 728 | xplayer-audio-preview |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index cc5f01ead..7391a8994 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -359,6 +359,7 @@ char *guess_shell(void); | |||
359 | // sandbox.c | 359 | // sandbox.c |
360 | int sandbox(void* sandbox_arg); | 360 | int sandbox(void* sandbox_arg); |
361 | void start_application(int no_sandbox, FILE *fp); | 361 | void start_application(int no_sandbox, FILE *fp); |
362 | void set_apparmor(void); | ||
362 | 363 | ||
363 | // network_main.c | 364 | // network_main.c |
364 | void net_configure_sandbox_ip(Bridge *br); | 365 | void net_configure_sandbox_ip(Bridge *br); |
diff --git a/src/firejail/fs_dev.c b/src/firejail/fs_dev.c index 500b6bf1b..fbce72429 100644 --- a/src/firejail/fs_dev.c +++ b/src/firejail/fs_dev.c | |||
@@ -157,9 +157,6 @@ static void create_link(const char *oldpath, const char *newpath) { | |||
157 | fprintf(stderr, "Error: cannot create %s device\n", newpath); | 157 | fprintf(stderr, "Error: cannot create %s device\n", newpath); |
158 | exit(1); | 158 | exit(1); |
159 | } | 159 | } |
160 | |||
161 | if (chown(newpath, 0, 0) < 0) {;} | ||
162 | |||
163 | fs_logger2("create", newpath); | 160 | fs_logger2("create", newpath); |
164 | return; | 161 | return; |
165 | } | 162 | } |
@@ -302,12 +299,10 @@ void fs_private_dev(void){ | |||
302 | fs_logger("clone /dev/pts"); | 299 | fs_logger("clone /dev/pts"); |
303 | 300 | ||
304 | // stdin, stdout, stderr | 301 | // stdin, stdout, stderr |
305 | #if 0 | ||
306 | create_link("/proc/self/fd", "/dev/fd"); | 302 | create_link("/proc/self/fd", "/dev/fd"); |
307 | create_link("/proc/self/fd/0", "/dev/stdin"); | 303 | create_link("/proc/self/fd/0", "/dev/stdin"); |
308 | create_link("/proc/self/fd/1", "/dev/stdout"); | 304 | create_link("/proc/self/fd/1", "/dev/stdout"); |
309 | create_link("/proc/self/fd/2", "/dev/stderr"); | 305 | create_link("/proc/self/fd/2", "/dev/stderr"); |
310 | #endif | ||
311 | 306 | ||
312 | // symlinks for DVD/CD players | 307 | // symlinks for DVD/CD players |
313 | if (stat("/dev/sr0", &s) == 0) { | 308 | if (stat("/dev/sr0", &s) == 0) { |
diff --git a/src/firejail/join.c b/src/firejail/join.c index 531f8c06a..fa1f64333 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c | |||
@@ -26,7 +26,11 @@ | |||
26 | 26 | ||
27 | #include <sys/prctl.h> | 27 | #include <sys/prctl.h> |
28 | #ifndef PR_SET_NO_NEW_PRIVS | 28 | #ifndef PR_SET_NO_NEW_PRIVS |
29 | # define PR_SET_NO_NEW_PRIVS 38 | 29 | #define PR_SET_NO_NEW_PRIVS 38 |
30 | #endif | ||
31 | |||
32 | #ifdef HAVE_APPARMOR | ||
33 | #include <sys/apparmor.h> | ||
30 | #endif | 34 | #endif |
31 | 35 | ||
32 | static int apply_caps = 0; | 36 | static int apply_caps = 0; |
@@ -50,6 +54,46 @@ static void install_handler(void) { | |||
50 | sigaction(SIGTERM, &sga, NULL); | 54 | sigaction(SIGTERM, &sga, NULL); |
51 | } | 55 | } |
52 | 56 | ||
57 | #ifdef HAVE_APPARMOR | ||
58 | static void extract_apparmor(pid_t pid) { | ||
59 | if (checkcfg(CFG_APPARMOR)) { | ||
60 | EUID_USER(); | ||
61 | if (aa_is_enabled() == 1) { | ||
62 | // get pid of next child process | ||
63 | pid_t child; | ||
64 | if (find_child(pid, &child) == 1) | ||
65 | child = pid; // no child, proceed with current pid | ||
66 | |||
67 | // get name of AppArmor profile | ||
68 | char *fname; | ||
69 | if (asprintf(&fname, "/proc/%d/attr/current", child) == -1) | ||
70 | errExit("asprintf"); | ||
71 | EUID_ROOT(); | ||
72 | int fd = open(fname, O_RDONLY|O_CLOEXEC); | ||
73 | EUID_USER(); | ||
74 | free(fname); | ||
75 | if (fd == -1) | ||
76 | goto errexit; | ||
77 | char buf[BUFLEN]; | ||
78 | ssize_t rv = read(fd, buf, sizeof(buf) - 1); | ||
79 | close(fd); | ||
80 | if (rv < 0) | ||
81 | goto errexit; | ||
82 | buf[rv] = '\0'; | ||
83 | // process confined by Firejail's AppArmor policy? | ||
84 | if (strncmp(buf, "firejail-default", 16) == 0) | ||
85 | arg_apparmor = 1; | ||
86 | } | ||
87 | EUID_ROOT(); | ||
88 | } | ||
89 | return; | ||
90 | |||
91 | errexit: | ||
92 | fprintf(stderr, "Error: cannot read /proc file\n"); | ||
93 | exit(1); | ||
94 | } | ||
95 | #endif // HAVE_APPARMOR | ||
96 | |||
53 | static void extract_x11_display(pid_t pid) { | 97 | static void extract_x11_display(pid_t pid) { |
54 | char *fname; | 98 | char *fname; |
55 | if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_X11_DIR, pid) == -1) | 99 | if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_X11_DIR, pid) == -1) |
@@ -388,6 +432,9 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
388 | extract_cgroup(pid); | 432 | extract_cgroup(pid); |
389 | extract_nogroups(pid); | 433 | extract_nogroups(pid); |
390 | extract_user_namespace(pid); | 434 | extract_user_namespace(pid); |
435 | #ifdef HAVE_APPARMOR | ||
436 | extract_apparmor(pid); | ||
437 | #endif | ||
391 | } | 438 | } |
392 | 439 | ||
393 | // set cgroup | 440 | // set cgroup |
@@ -501,6 +548,11 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
501 | // kill the child in case the parent died | 548 | // kill the child in case the parent died |
502 | prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); | 549 | prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); |
503 | 550 | ||
551 | #ifdef HAVE_APPARMOR | ||
552 | // add apparmor confinement after the execve | ||
553 | set_apparmor(); | ||
554 | #endif | ||
555 | |||
504 | extract_command(argc, argv, index); | 556 | extract_command(argc, argv, index); |
505 | if (cfg.command_line == NULL) { | 557 | if (cfg.command_line == NULL) { |
506 | assert(cfg.shell); | 558 | assert(cfg.shell); |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index d1d98f636..d1879fd98 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <dirent.h> | 29 | #include <dirent.h> |
30 | #include <errno.h> | 30 | #include <errno.h> |
31 | #include <fcntl.h> | 31 | #include <fcntl.h> |
32 | #include <syscall.h> | ||
32 | 33 | ||
33 | #include <sched.h> | 34 | #include <sched.h> |
34 | #ifndef CLONE_NEWUSER | 35 | #ifndef CLONE_NEWUSER |
@@ -37,16 +38,15 @@ | |||
37 | 38 | ||
38 | #include <sys/prctl.h> | 39 | #include <sys/prctl.h> |
39 | #ifndef PR_SET_NO_NEW_PRIVS | 40 | #ifndef PR_SET_NO_NEW_PRIVS |
40 | # define PR_SET_NO_NEW_PRIVS 38 | 41 | #define PR_SET_NO_NEW_PRIVS 38 |
41 | #endif | 42 | #endif |
42 | #ifndef PR_GET_NO_NEW_PRIVS | 43 | #ifndef PR_GET_NO_NEW_PRIVS |
43 | # define PR_GET_NO_NEW_PRIVS 39 | 44 | #define PR_GET_NO_NEW_PRIVS 39 |
44 | #endif | 45 | #endif |
45 | 46 | ||
46 | #ifdef HAVE_APPARMOR | 47 | #ifdef HAVE_APPARMOR |
47 | #include <sys/apparmor.h> | 48 | #include <sys/apparmor.h> |
48 | #endif | 49 | #endif |
49 | #include <syscall.h> | ||
50 | 50 | ||
51 | 51 | ||
52 | static int force_nonewprivs = 0; | 52 | static int force_nonewprivs = 0; |
@@ -125,6 +125,21 @@ static void set_caps(void) { | |||
125 | caps_drop_dac_override(); | 125 | caps_drop_dac_override(); |
126 | } | 126 | } |
127 | 127 | ||
128 | #ifdef HAVE_APPARMOR | ||
129 | void set_apparmor(void) { | ||
130 | EUID_ASSERT(); | ||
131 | if (checkcfg(CFG_APPARMOR) && arg_apparmor) { | ||
132 | if (aa_change_onexec("firejail-default")) { | ||
133 | fwarning("Cannot confine the application using AppArmor.\n" | ||
134 | "Maybe firejail-default AppArmor profile is not loaded into the kernel.\n" | ||
135 | "As root, run \"aa-enforce firejail-default\" to load it.\n"); | ||
136 | } | ||
137 | else if (arg_debug) | ||
138 | printf("AppArmor enabled\n"); | ||
139 | } | ||
140 | } | ||
141 | #endif | ||
142 | |||
128 | static void save_nogroups(void) { | 143 | static void save_nogroups(void) { |
129 | if (arg_nogroups == 0) | 144 | if (arg_nogroups == 0) |
130 | return; | 145 | return; |
@@ -1203,17 +1218,10 @@ int sandbox(void* sandbox_arg) { | |||
1203 | 1218 | ||
1204 | if (app_pid == 0) { | 1219 | if (app_pid == 0) { |
1205 | #ifdef HAVE_APPARMOR | 1220 | #ifdef HAVE_APPARMOR |
1206 | if (checkcfg(CFG_APPARMOR) && arg_apparmor) { | 1221 | // add apparmor confinement after the execve |
1207 | errno = 0; | 1222 | set_apparmor(); |
1208 | if (aa_change_onexec("firejail-default")) { | ||
1209 | fwarning("Cannot confine the application using AppArmor.\n" | ||
1210 | "Maybe firejail-default AppArmor profile is not loaded into the kernel.\n" | ||
1211 | "As root, run \"aa-enforce firejail-default\" to load it.\n"); | ||
1212 | } | ||
1213 | else if (arg_debug) | ||
1214 | printf("AppArmor enabled\n"); | ||
1215 | } | ||
1216 | #endif | 1223 | #endif |
1224 | |||
1217 | // set nice and rlimits | 1225 | // set nice and rlimits |
1218 | if (arg_nice) | 1226 | if (arg_nice) |
1219 | set_nice(cfg.nice); | 1227 | set_nice(cfg.nice); |
diff --git a/src/firejail/sbox.c b/src/firejail/sbox.c index c3b68f3a8..0c7b13f1c 100644 --- a/src/firejail/sbox.c +++ b/src/firejail/sbox.c | |||
@@ -53,11 +53,17 @@ static struct sock_filter filter[] = { | |||
53 | #ifdef SYS_ptrace | 53 | #ifdef SYS_ptrace |
54 | BLACKLIST(SYS_ptrace), // trace processes | 54 | BLACKLIST(SYS_ptrace), // trace processes |
55 | #endif | 55 | #endif |
56 | #ifdef SYS_process_vm_readv | ||
57 | BLACKLIST(SYS_process_vm_readv), | ||
58 | #endif | ||
59 | #ifdef SYS_process_vm_writev | ||
60 | BLACKLIST(SYS_process_vm_writev), | ||
61 | #endif | ||
56 | #ifdef SYS_kexec_file_load | 62 | #ifdef SYS_kexec_file_load |
57 | BLACKLIST(SYS_kexec_file_load), | 63 | BLACKLIST(SYS_kexec_file_load), // loading a different kernel |
58 | #endif | 64 | #endif |
59 | #ifdef SYS_kexec_load | 65 | #ifdef SYS_kexec_load |
60 | BLACKLIST(SYS_kexec_load), // loading a different kernel | 66 | BLACKLIST(SYS_kexec_load), |
61 | #endif | 67 | #endif |
62 | #ifdef SYS_name_to_handle_at | 68 | #ifdef SYS_name_to_handle_at |
63 | BLACKLIST(SYS_name_to_handle_at), | 69 | BLACKLIST(SYS_name_to_handle_at), |
@@ -83,9 +89,6 @@ static struct sock_filter filter[] = { | |||
83 | #ifdef SYS_ioperm | 89 | #ifdef SYS_ioperm |
84 | BLACKLIST(SYS_ioperm), | 90 | BLACKLIST(SYS_ioperm), |
85 | #endif | 91 | #endif |
86 | #ifdef SYS_iopl | ||
87 | BLACKLIST(SYS_iopl), // io permissions | ||
88 | #endif | ||
89 | #ifdef SYS_ioprio_set | 92 | #ifdef SYS_ioprio_set |
90 | BLACKLIST(SYS_ioprio_set), | 93 | BLACKLIST(SYS_ioprio_set), |
91 | #endif | 94 | #endif |