Add support for custom AppArmor profiles (--apparmor=)

This commit is contained in:
Азалия Смарагдова 2022-07-25 17:16:53 +05:00
parent 74b5d24ba3
commit 7f3b6c19a0
No known key found for this signature in database
GPG key ID: 6E97B77BB39B5649
9 changed files with 39 additions and 7 deletions

View file

@ -52,7 +52,7 @@ syn match fjVar /\v\$\{(CFG|DESKTOP|DOCUMENTS|DOWNLOADS|HOME|MUSIC|PATH|PICTURES
" Commands grabbed from: src/firejail/profile.c " Commands grabbed from: src/firejail/profile.c
" Generate list with: { rg -o 'strn?cmp\(ptr, "([^"]+) "' -r '$1' src/firejail/profile.c; echo private-lib; } | grep -vEx '(include|ignore|caps\.drop|caps\.keep|protocol|restrict-namespaces|seccomp|seccomp\.drop|seccomp\.keep|env|rmenv|net|ip)' | sort -u | tr $'\n' '|' # private-lib is special-cased in the code and doesn't match the regex; grep-ed patterns are handled later with 'syn match nextgroup=' directives (except for include which is special-cased as a fjCommandNoCond keyword) " Generate list with: { rg -o 'strn?cmp\(ptr, "([^"]+) "' -r '$1' src/firejail/profile.c; echo private-lib; } | grep -vEx '(include|ignore|caps\.drop|caps\.keep|protocol|restrict-namespaces|seccomp|seccomp\.drop|seccomp\.keep|env|rmenv|net|ip)' | sort -u | tr $'\n' '|' # private-lib is special-cased in the code and doesn't match the regex; grep-ed patterns are handled later with 'syn match nextgroup=' directives (except for include which is special-cased as a fjCommandNoCond keyword)
syn match fjCommand /\v(bind|blacklist|blacklist-nolog|cpu|defaultgw|dns|hostname|hosts-file|ip6|iprange|join-or-start|mac|mkdir|mkfile|mtu|name|netfilter|netfilter6|netmask|nice|noblacklist|noexec|nowhitelist|overlay-named|private|private-bin|private-cwd|private-etc|private-home|private-lib|private-opt|private-srv|read-only|read-write|rlimit-as|rlimit-cpu|rlimit-fsize|rlimit-nofile|rlimit-nproc|rlimit-sigpending|timeout|tmpfs|veth-name|whitelist|xephyr-screen) / skipwhite contained syn match fjCommand /\v(apparmor|bind|blacklist|blacklist-nolog|cpu|defaultgw|dns|hostname|hosts-file|ip6|iprange|join-or-start|mac|mkdir|mkfile|mtu|name|netfilter|netfilter6|netmask|nice|noblacklist|noexec|nowhitelist|overlay-named|private|private-bin|private-cwd|private-etc|private-home|private-lib|private-opt|private-srv|read-only|read-write|rlimit-as|rlimit-cpu|rlimit-fsize|rlimit-nofile|rlimit-nproc|rlimit-sigpending|timeout|tmpfs|veth-name|whitelist|xephyr-screen) / skipwhite contained
" Generate list with: rg -o 'strn?cmp\(ptr, "([^ "]*[^ ])"' -r '$1' src/firejail/profile.c | grep -vEx '(include|rlimit|quiet)' | sed -e 's/\./\\./' | sort -u | tr $'\n' '|' # include/rlimit are false positives, quiet is special-cased below " Generate list with: rg -o 'strn?cmp\(ptr, "([^ "]*[^ ])"' -r '$1' src/firejail/profile.c | grep -vEx '(include|rlimit|quiet)' | sed -e 's/\./\\./' | sort -u | tr $'\n' '|' # include/rlimit are false positives, quiet is special-cased below
syn match fjCommand /\v(allow-debuggers|allusers|apparmor|caps|deterministic-exit-code|deterministic-shutdown|disable-mnt|ipc-namespace|keep-config-pulse|keep-dev-shm|keep-fd|keep-var-tmp|machine-id|memory-deny-write-execute|netfilter|no3d|noautopulse|nodbus|nodvd|nogroups|noinput|nonewprivs|noprinters|noroot|nosound|notv|nou2f|novideo|overlay|overlay-tmpfs|private|private-cache|private-cwd|private-dev|private-lib|private-tmp|seccomp|seccomp\.32|seccomp\.block-secondary|tracelog|writable-etc|writable-run-user|writable-var|writable-var-log|x11)$/ contained syn match fjCommand /\v(allow-debuggers|allusers|apparmor|caps|deterministic-exit-code|deterministic-shutdown|disable-mnt|ipc-namespace|keep-config-pulse|keep-dev-shm|keep-fd|keep-var-tmp|machine-id|memory-deny-write-execute|netfilter|no3d|noautopulse|nodbus|nodvd|nogroups|noinput|nonewprivs|noprinters|noroot|nosound|notv|nou2f|novideo|overlay|overlay-tmpfs|private|private-cache|private-cwd|private-dev|private-lib|private-tmp|seccomp|seccomp\.32|seccomp\.block-secondary|tracelog|writable-etc|writable-run-user|writable-var|writable-var-log|x11)$/ contained
syn match fjCommand /ignore / nextgroup=fjCommand,fjCommandNoCond skipwhite contained syn match fjCommand /ignore / nextgroup=fjCommand,fjCommandNoCond skipwhite contained

View file

@ -338,6 +338,7 @@ extern int arg_writable_run_user; // writable /run/user
extern int arg_writable_var_log; // writable /var/log extern int arg_writable_var_log; // writable /var/log
extern int arg_appimage; // appimage extern int arg_appimage; // appimage
extern int arg_apparmor; // apparmor extern int arg_apparmor; // apparmor
extern char *apparmor_profile; // apparmor profile
extern int arg_allow_debuggers; // allow debuggers extern int arg_allow_debuggers; // allow debuggers
extern int arg_x11_block; // block X11 extern int arg_x11_block; // block X11
extern int arg_x11_xorg; // use X11 security extension extern int arg_x11_xorg; // use X11 security extension

View file

@ -133,6 +133,7 @@ int arg_writable_run_user = 0; // writable /run/user
int arg_writable_var_log = 0; // writable /var/log int arg_writable_var_log = 0; // writable /var/log
int arg_appimage = 0; // appimage int arg_appimage = 0; // appimage
int arg_apparmor = 0; // apparmor int arg_apparmor = 0; // apparmor
char *apparmor_profile = NULL; // apparmor profile
int arg_allow_debuggers = 0; // allow debuggers int arg_allow_debuggers = 0; // allow debuggers
int arg_x11_block = 0; // block X11 int arg_x11_block = 0; // block X11
int arg_x11_xorg = 0; // use X11 security extension int arg_x11_xorg = 0; // use X11 security extension
@ -1287,8 +1288,14 @@ int main(int argc, char **argv, char **envp) {
// filtering // filtering
//************************************* //*************************************
#ifdef HAVE_APPARMOR #ifdef HAVE_APPARMOR
else if (strcmp(argv[i], "--apparmor") == 0) else if (strcmp(argv[i], "--apparmor") == 0) {
arg_apparmor = 1; arg_apparmor = 1;
apparmor_profile = "firejail-default";
}
else if (strncmp(argv[i], "--apparmor=", 11) == 0) {
arg_apparmor = 1;
apparmor_profile = argv[i] + 11;
}
#endif #endif
else if (strncmp(argv[i], "--protocol=", 11) == 0) { else if (strncmp(argv[i], "--protocol=", 11) == 0) {
if (checkcfg(CFG_SECCOMP)) { if (checkcfg(CFG_SECCOMP)) {

View file

@ -939,6 +939,17 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
if (strcmp(ptr, "apparmor") == 0) { if (strcmp(ptr, "apparmor") == 0) {
#ifdef HAVE_APPARMOR #ifdef HAVE_APPARMOR
arg_apparmor = 1; arg_apparmor = 1;
apparmor_profile = "firejail-default";
#endif
return 0;
}
if (strncmp(ptr, "apparmor ", 9) == 0) {
#ifdef HAVE_APPARMOR
arg_apparmor = 1;
apparmor_profile = strdup(ptr + 9);
if (!apparmor_profile)
errExit("strdup");
#endif #endif
return 0; return 0;
} }

View file

@ -130,7 +130,7 @@ static void set_caps(void) {
static void set_apparmor(void) { static void set_apparmor(void) {
EUID_ASSERT(); EUID_ASSERT();
if (checkcfg(CFG_APPARMOR) && arg_apparmor) { if (checkcfg(CFG_APPARMOR) && arg_apparmor) {
if (aa_change_onexec("firejail-default")) { if (aa_stack_onexec(apparmor_profile)) {
fwarning("Cannot confine the application using AppArmor.\n" fwarning("Cannot confine the application using AppArmor.\n"
"Maybe firejail-default AppArmor profile is not loaded into the kernel.\n" "Maybe firejail-default AppArmor profile is not loaded into the kernel.\n"
"As root, run \"aa-enforce firejail-default\" to load it.\n"); "As root, run \"aa-enforce firejail-default\" to load it.\n");

View file

@ -30,7 +30,9 @@ static char *usage_str =
" -- - signal the end of options and disables further option processing.\n" " -- - signal the end of options and disables further option processing.\n"
" --allow-debuggers - allow tools such as strace and gdb inside the sandbox.\n" " --allow-debuggers - allow tools such as strace and gdb inside the sandbox.\n"
" --allusers - all user home directories are visible inside the sandbox.\n" " --allusers - all user home directories are visible inside the sandbox.\n"
" --apparmor - enable AppArmor confinement.\n" " --apparmor - enable AppArmor confinement with the default profile.\n"
" --apparmor=profile_name - enable AppArmor confinement with a\n"
"\tcustom profile.\n"
" --apparmor.print=name|pid - print apparmor status.\n" " --apparmor.print=name|pid - print apparmor status.\n"
" --appimage - sandbox an AppImage application.\n" " --appimage - sandbox an AppImage application.\n"
#ifdef HAVE_NETWORK #ifdef HAVE_NETWORK

View file

@ -478,7 +478,11 @@ Allow tools such as strace and gdb inside the sandbox by whitelisting system cal
#ifdef HAVE_APPARMOR #ifdef HAVE_APPARMOR
.TP .TP
\fBapparmor \fBapparmor
Enable AppArmor confinement. Enable AppArmor confinement with the "firejail-default" AppArmor profile.
.TP
\fBapparmor profile_name
Enable AppArmor confinement with a custom AppArmor profile.
Note that the profile in question must already be loaded into the kernel.
#endif #endif
.TP .TP
\fBcaps \fBcaps

View file

@ -122,7 +122,13 @@ $ firejail --allusers
#ifdef HAVE_APPARMOR #ifdef HAVE_APPARMOR
.TP .TP
\fB\-\-apparmor \fB\-\-apparmor
Enable AppArmor confinement. For more information, please see \fBAPPARMOR\fR section below. Enable AppArmor confinement with the "firejail-default" AppArmor profile.
For more information, please see \fBAPPARMOR\fR section below.
.TP
\fB\-\-apparmor=profile_name
Enable AppArmor confinement with a custom AppArmor profile.
Note that profile in question must already be loaded into the kernel.
For more information, please see \fBAPPARMOR\fR section below.
.TP .TP
\fB\-\-apparmor.print=name|pid \fB\-\-apparmor.print=name|pid
Print the AppArmor confinement status for the sandbox identified by name or by PID. Print the AppArmor confinement status for the sandbox identified by name or by PID.

View file

@ -171,7 +171,8 @@ _firejail_args=(
'--writable-var-log[use the real /var/log directory, not a clone]' '--writable-var-log[use the real /var/log directory, not a clone]'
#ifdef HAVE_APPARMOR #ifdef HAVE_APPARMOR
'--apparmor[enable AppArmor confinement]' '--apparmor[enable AppArmor confinement with the default profile]'
'--apparmor=-[enable AppArmor confinement with a custom profile]: :'
'--apparmor.print=-[print apparmor status name|pid]:firejail:_all_firejails' '--apparmor.print=-[print apparmor status name|pid]:firejail:_all_firejails'
#endif #endif