aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2020-03-02 14:16:17 +0100
committerLibravatar GitHub <noreply@github.com>2020-03-02 14:16:17 +0100
commitff4b3c8939f7616b0b901104b71e8ac30ebc9ab9 (patch)
tree8ea56af51775abf907b40b0d0da6c64d04455980 /src
parentMerge pull request #3255 from curiosityseeker/master (diff)
downloadfirejail-ff4b3c8939f7616b0b901104b71e8ac30ebc9ab9.tar.gz
firejail-ff4b3c8939f7616b0b901104b71e8ac30ebc9ab9.tar.zst
firejail-ff4b3c8939f7616b0b901104b71e8ac30ebc9ab9.zip
integrate AppArmor with join options (#3242)
add AppArmor confinement to processes started with --join and, more importantly, --join-or-start
Diffstat (limited to 'src')
-rw-r--r--src/firejail/firejail.h1
-rw-r--r--src/firejail/join.c54
-rw-r--r--src/firejail/sandbox.c34
3 files changed, 75 insertions, 14 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 66328a55e..0e4fcea6a 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
360int sandbox(void* sandbox_arg); 360int sandbox(void* sandbox_arg);
361void start_application(int no_sandbox, FILE *fp); 361void start_application(int no_sandbox, FILE *fp);
362void set_apparmor(void);
362 363
363// network_main.c 364// network_main.c
364void net_configure_sandbox_ip(Bridge *br); 365void net_configure_sandbox_ip(Bridge *br);
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
32static int apply_caps = 0; 36static 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
58static 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
91errexit:
92 fprintf(stderr, "Error: cannot read /proc file\n");
93 exit(1);
94}
95#endif // HAVE_APPARMOR
96
53static void extract_x11_display(pid_t pid) { 97static 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
52static int force_nonewprivs = 0; 52static 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
129void 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
128static void save_nogroups(void) { 143static 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);