diff options
-rw-r--r-- | README | 3 | ||||
-rw-r--r-- | config.mk.in | 2 | ||||
-rwxr-xr-x | configure | 86 | ||||
-rw-r--r-- | configure.ac | 12 | ||||
-rw-r--r-- | contrib/syntax/lists/profile_commands_arg0.list | 1 | ||||
-rw-r--r-- | contrib/syntax/lists/profile_commands_arg1.list | 5 | ||||
-rw-r--r-- | src/bash_completion/firejail.bash_completion.in | 19 | ||||
-rw-r--r-- | src/firejail/checkcfg.c | 7 | ||||
-rw-r--r-- | src/firejail/firejail.h | 22 | ||||
-rw-r--r-- | src/firejail/landlock.c | 263 | ||||
-rw-r--r-- | src/firejail/main.c | 28 | ||||
-rw-r--r-- | src/firejail/profile.c | 38 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 22 | ||||
-rw-r--r-- | src/firejail/usage.c | 8 | ||||
-rw-r--r-- | src/firejail/util.c | 7 | ||||
-rw-r--r-- | src/man/firejail-profile.5.in | 31 | ||||
-rw-r--r-- | src/man/firejail.1.in | 87 | ||||
-rw-r--r-- | src/zsh_completion/_firejail.in | 5 |
18 files changed, 616 insertions, 30 deletions
@@ -197,7 +197,8 @@ avoidr (https://github.com/avoidr) | |||
197 | - fixed mpv profile | 197 | - fixed mpv profile |
198 | - various other fixes | 198 | - various other fixes |
199 | Азалия Смарагдова/ChrysoliteAzalea (https://github.com/ChrysoliteAzalea) | 199 | Азалия Смарагдова/ChrysoliteAzalea (https://github.com/ChrysoliteAzalea) |
200 | - add support for custom AppArmor profiles (--apparmor=) | 200 | - add support for custom AppArmor profiles (--apparmor=) |
201 | - add Landlock support | ||
201 | backspac (https://github.com/backspac) | 202 | backspac (https://github.com/backspac) |
202 | - firecfg fixes | 203 | - firecfg fixes |
203 | - add steam-runtime alias | 204 | - add steam-runtime alias |
diff --git a/config.mk.in b/config.mk.in index c76ca1a98..d50c7d2f5 100644 --- a/config.mk.in +++ b/config.mk.in | |||
@@ -38,6 +38,7 @@ HAVE_FIRETUNNEL=@HAVE_FIRETUNNEL@ | |||
38 | HAVE_FORCE_NONEWPRIVS=@HAVE_FORCE_NONEWPRIVS@ | 38 | HAVE_FORCE_NONEWPRIVS=@HAVE_FORCE_NONEWPRIVS@ |
39 | HAVE_GLOBALCFG=@HAVE_GLOBALCFG@ | 39 | HAVE_GLOBALCFG=@HAVE_GLOBALCFG@ |
40 | HAVE_IDS=@HAVE_IDS@ | 40 | HAVE_IDS=@HAVE_IDS@ |
41 | HAVE_LANDLOCK=@HAVE_LANDLOCK@ | ||
41 | HAVE_LTS=@HAVE_LTS@ | 42 | HAVE_LTS=@HAVE_LTS@ |
42 | HAVE_NETWORK=@HAVE_NETWORK@ | 43 | HAVE_NETWORK=@HAVE_NETWORK@ |
43 | HAVE_ONLY_SYSCFG_PROFILES=@HAVE_ONLY_SYSCFG_PROFILES@ | 44 | HAVE_ONLY_SYSCFG_PROFILES=@HAVE_ONLY_SYSCFG_PROFILES@ |
@@ -60,6 +61,7 @@ MANFLAGS = \ | |||
60 | $(HAVE_FORCE_NONEWPRIVS) \ | 61 | $(HAVE_FORCE_NONEWPRIVS) \ |
61 | $(HAVE_GLOBALCFG) \ | 62 | $(HAVE_GLOBALCFG) \ |
62 | $(HAVE_IDS) \ | 63 | $(HAVE_IDS) \ |
64 | $(HAVE_LANDLOCK) \ | ||
63 | $(HAVE_LTS) \ | 65 | $(HAVE_LTS) \ |
64 | $(HAVE_NETWORK) \ | 66 | $(HAVE_NETWORK) \ |
65 | $(HAVE_ONLY_SYSCFG_PROFILES) \ | 67 | $(HAVE_ONLY_SYSCFG_PROFILES) \ |
@@ -675,6 +675,7 @@ HAVE_OVERLAYFS | |||
675 | HAVE_DBUSPROXY | 675 | HAVE_DBUSPROXY |
676 | EXTRA_LDFLAGS | 676 | EXTRA_LDFLAGS |
677 | EXTRA_CFLAGS | 677 | EXTRA_CFLAGS |
678 | HAVE_LANDLOCK | ||
678 | HAVE_SELINUX | 679 | HAVE_SELINUX |
679 | AA_LIBS | 680 | AA_LIBS |
680 | AA_CFLAGS | 681 | AA_CFLAGS |
@@ -737,6 +738,7 @@ enable_sanitizer | |||
737 | enable_ids | 738 | enable_ids |
738 | enable_apparmor | 739 | enable_apparmor |
739 | enable_selinux | 740 | enable_selinux |
741 | enable_landlock | ||
740 | enable_dbusproxy | 742 | enable_dbusproxy |
741 | enable_output | 743 | enable_output |
742 | enable_usertmpfs | 744 | enable_usertmpfs |
@@ -1396,6 +1398,7 @@ Optional Features: | |||
1396 | --enable-ids enable ids | 1398 | --enable-ids enable ids |
1397 | --enable-apparmor enable apparmor | 1399 | --enable-apparmor enable apparmor |
1398 | --enable-selinux SELinux labeling support | 1400 | --enable-selinux SELinux labeling support |
1401 | --enable-landlock Landlock self-restriction support | ||
1399 | --disable-dbusproxy disable dbus proxy | 1402 | --disable-dbusproxy disable dbus proxy |
1400 | --disable-output disable --output logging | 1403 | --disable-output disable --output logging |
1401 | --disable-usertmpfs disable tmpfs as regular user | 1404 | --disable-usertmpfs disable tmpfs as regular user |
@@ -3739,6 +3742,58 @@ then : | |||
3739 | 3742 | ||
3740 | fi | 3743 | fi |
3741 | 3744 | ||
3745 | HAVE_LANDLOCK="" | ||
3746 | |||
3747 | # Check whether --enable-landlock was given. | ||
3748 | if test ${enable_landlock+y} | ||
3749 | then : | ||
3750 | enableval=$enable_landlock; | ||
3751 | fi | ||
3752 | |||
3753 | ac_header= ac_cache= | ||
3754 | for ac_item in $ac_header_c_list | ||
3755 | do | ||
3756 | if test $ac_cache; then | ||
3757 | ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" | ||
3758 | if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then | ||
3759 | printf "%s\n" "#define $ac_item 1" >> confdefs.h | ||
3760 | fi | ||
3761 | ac_header= ac_cache= | ||
3762 | elif test $ac_header; then | ||
3763 | ac_cache=$ac_item | ||
3764 | else | ||
3765 | ac_header=$ac_item | ||
3766 | fi | ||
3767 | done | ||
3768 | |||
3769 | |||
3770 | |||
3771 | |||
3772 | |||
3773 | |||
3774 | |||
3775 | |||
3776 | if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes | ||
3777 | then : | ||
3778 | |||
3779 | printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h | ||
3780 | |||
3781 | fi | ||
3782 | if test "x$enable_landlock" != "xno" | ||
3783 | then : | ||
3784 | |||
3785 | ac_fn_c_check_header_compile "$LINENO" "linux/landlock.h" "ac_cv_header_linux_landlock_h" "$ac_includes_default" | ||
3786 | if test "x$ac_cv_header_linux_landlock_h" = xyes | ||
3787 | then : | ||
3788 | HAVE_LANDLOCK="-DHAVE_LANDLOCK" | ||
3789 | else $as_nop | ||
3790 | { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: header not found: linux/landlock.h, building without Landlock support" >&5 | ||
3791 | printf "%s\n" "$as_me: WARNING: header not found: linux/landlock.h, building without Landlock support" >&2;} | ||
3792 | fi | ||
3793 | |||
3794 | |||
3795 | fi | ||
3796 | |||
3742 | 3797 | ||
3743 | 3798 | ||
3744 | 3799 | ||
@@ -4112,6 +4167,7 @@ if test "x$enable_lts" = "xyes" | |||
4112 | then : | 4167 | then : |
4113 | 4168 | ||
4114 | HAVE_LTS="-DHAVE_LTS" | 4169 | HAVE_LTS="-DHAVE_LTS" |
4170 | HAVE_LANDLOCK="" | ||
4115 | HAVE_IDS="" | 4171 | HAVE_IDS="" |
4116 | HAVE_DBUSPROXY="" | 4172 | HAVE_DBUSPROXY="" |
4117 | HAVE_OVERLAYFS="" | 4173 | HAVE_OVERLAYFS="" |
@@ -4132,35 +4188,6 @@ then : | |||
4132 | 4188 | ||
4133 | fi | 4189 | fi |
4134 | 4190 | ||
4135 | ac_header= ac_cache= | ||
4136 | for ac_item in $ac_header_c_list | ||
4137 | do | ||
4138 | if test $ac_cache; then | ||
4139 | ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" | ||
4140 | if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then | ||
4141 | printf "%s\n" "#define $ac_item 1" >> confdefs.h | ||
4142 | fi | ||
4143 | ac_header= ac_cache= | ||
4144 | elif test $ac_header; then | ||
4145 | ac_cache=$ac_item | ||
4146 | else | ||
4147 | ac_header=$ac_item | ||
4148 | fi | ||
4149 | done | ||
4150 | |||
4151 | |||
4152 | |||
4153 | |||
4154 | |||
4155 | |||
4156 | |||
4157 | |||
4158 | if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes | ||
4159 | then : | ||
4160 | |||
4161 | printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h | ||
4162 | |||
4163 | fi | ||
4164 | ac_fn_c_check_header_compile "$LINENO" "linux/seccomp.h" "ac_cv_header_linux_seccomp_h" "$ac_includes_default" | 4191 | ac_fn_c_check_header_compile "$LINENO" "linux/seccomp.h" "ac_cv_header_linux_seccomp_h" "$ac_includes_default" |
4165 | if test "x$ac_cv_header_linux_seccomp_h" = xyes | 4192 | if test "x$ac_cv_header_linux_seccomp_h" = xyes |
4166 | then : | 4193 | then : |
@@ -5360,6 +5387,7 @@ Features: | |||
5360 | firetunnel support: $HAVE_FIRETUNNEL | 5387 | firetunnel support: $HAVE_FIRETUNNEL |
5361 | global config: $HAVE_GLOBALCFG | 5388 | global config: $HAVE_GLOBALCFG |
5362 | IDS support: $HAVE_IDS | 5389 | IDS support: $HAVE_IDS |
5390 | Landlock support: $HAVE_LANDLOCK | ||
5363 | LTS: $HAVE_LTS | 5391 | LTS: $HAVE_LTS |
5364 | manpage support: $HAVE_MAN | 5392 | manpage support: $HAVE_MAN |
5365 | network: $HAVE_NETWORK | 5393 | network: $HAVE_NETWORK |
diff --git a/configure.ac b/configure.ac index 93de61b95..bd80150ed 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -81,6 +81,16 @@ AS_IF([test "x$enable_selinux" = "xyes"], [ | |||
81 | LIBS="$LIBS -lselinux" | 81 | LIBS="$LIBS -lselinux" |
82 | ]) | 82 | ]) |
83 | 83 | ||
84 | HAVE_LANDLOCK="" | ||
85 | AC_SUBST([HAVE_LANDLOCK]) | ||
86 | AC_ARG_ENABLE([landlock], | ||
87 | [AS_HELP_STRING([--enable-landlock], [Landlock self-restriction support])]) | ||
88 | AS_IF([test "x$enable_landlock" != "xno"], [ | ||
89 | AC_CHECK_HEADER([linux/landlock.h], | ||
90 | [HAVE_LANDLOCK="-DHAVE_LANDLOCK"], | ||
91 | [AC_MSG_WARN([header not found: linux/landlock.h, building without Landlock support])]) | ||
92 | ]) | ||
93 | |||
84 | AC_SUBST([EXTRA_CFLAGS]) | 94 | AC_SUBST([EXTRA_CFLAGS]) |
85 | AC_SUBST([EXTRA_LDFLAGS]) | 95 | AC_SUBST([EXTRA_LDFLAGS]) |
86 | 96 | ||
@@ -264,6 +274,7 @@ AC_ARG_ENABLE([lts], | |||
264 | [AS_HELP_STRING([--enable-lts], [enable long-term support software version (LTS)])]) | 274 | [AS_HELP_STRING([--enable-lts], [enable long-term support software version (LTS)])]) |
265 | AS_IF([test "x$enable_lts" = "xyes"], [ | 275 | AS_IF([test "x$enable_lts" = "xyes"], [ |
266 | HAVE_LTS="-DHAVE_LTS" | 276 | HAVE_LTS="-DHAVE_LTS" |
277 | HAVE_LANDLOCK="" | ||
267 | HAVE_IDS="" | 278 | HAVE_IDS="" |
268 | HAVE_DBUSPROXY="" | 279 | HAVE_DBUSPROXY="" |
269 | HAVE_OVERLAYFS="" | 280 | HAVE_OVERLAYFS="" |
@@ -324,6 +335,7 @@ Features: | |||
324 | firetunnel support: $HAVE_FIRETUNNEL | 335 | firetunnel support: $HAVE_FIRETUNNEL |
325 | global config: $HAVE_GLOBALCFG | 336 | global config: $HAVE_GLOBALCFG |
326 | IDS support: $HAVE_IDS | 337 | IDS support: $HAVE_IDS |
338 | Landlock support: $HAVE_LANDLOCK | ||
327 | LTS: $HAVE_LTS | 339 | LTS: $HAVE_LTS |
328 | manpage support: $HAVE_MAN | 340 | manpage support: $HAVE_MAN |
329 | network: $HAVE_NETWORK | 341 | network: $HAVE_NETWORK |
diff --git a/contrib/syntax/lists/profile_commands_arg0.list b/contrib/syntax/lists/profile_commands_arg0.list index e7fecef4b..4d49e96d9 100644 --- a/contrib/syntax/lists/profile_commands_arg0.list +++ b/contrib/syntax/lists/profile_commands_arg0.list | |||
@@ -12,6 +12,7 @@ keep-config-pulse | |||
12 | keep-dev-shm | 12 | keep-dev-shm |
13 | keep-shell-rc | 13 | keep-shell-rc |
14 | keep-var-tmp | 14 | keep-var-tmp |
15 | landlock | ||
15 | machine-id | 16 | machine-id |
16 | memory-deny-write-execute | 17 | memory-deny-write-execute |
17 | netfilter | 18 | netfilter |
diff --git a/contrib/syntax/lists/profile_commands_arg1.list b/contrib/syntax/lists/profile_commands_arg1.list index 5862f16ac..cce37efa0 100644 --- a/contrib/syntax/lists/profile_commands_arg1.list +++ b/contrib/syntax/lists/profile_commands_arg1.list | |||
@@ -29,6 +29,11 @@ ip6 | |||
29 | iprange | 29 | iprange |
30 | join-or-start | 30 | join-or-start |
31 | keep-fd | 31 | keep-fd |
32 | landlock.execute | ||
33 | landlock.proc | ||
34 | landlock.read | ||
35 | landlock.special | ||
36 | landlock.write | ||
32 | mac | 37 | mac |
33 | mkdir | 38 | mkdir |
34 | mkfile | 39 | mkfile |
diff --git a/src/bash_completion/firejail.bash_completion.in b/src/bash_completion/firejail.bash_completion.in index 98e3a035e..eab0f7df6 100644 --- a/src/bash_completion/firejail.bash_completion.in +++ b/src/bash_completion/firejail.bash_completion.in | |||
@@ -42,6 +42,25 @@ _firejail() | |||
42 | _filedir -d | 42 | _filedir -d |
43 | return 0 | 43 | return 0 |
44 | ;; | 44 | ;; |
45 | --landlock) | ||
46 | return 0 | ||
47 | ;; | ||
48 | --landlock.read) | ||
49 | _filedir | ||
50 | return 0 | ||
51 | ;; | ||
52 | --landlock.write) | ||
53 | _filedir | ||
54 | return 0 | ||
55 | ;; | ||
56 | --landlock.special) | ||
57 | _filedir | ||
58 | return 0 | ||
59 | ;; | ||
60 | --landlock.execute) | ||
61 | _filedir | ||
62 | return 0 | ||
63 | ;; | ||
45 | --tmpfs) | 64 | --tmpfs) |
46 | _filedir | 65 | _filedir |
47 | return 0 | 66 | return 0 |
diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c index d2289bb40..7792c6541 100644 --- a/src/firejail/checkcfg.c +++ b/src/firejail/checkcfg.c | |||
@@ -363,6 +363,13 @@ static const char *const compiletime_support = | |||
363 | "disabled" | 363 | "disabled" |
364 | #endif | 364 | #endif |
365 | 365 | ||
366 | "\n\t- Landlock support is " | ||
367 | #ifdef HAVE_LANDLOCK | ||
368 | "enabled" | ||
369 | #else | ||
370 | "disabled" | ||
371 | #endif | ||
372 | |||
366 | "\n\t- networking support is " | 373 | "\n\t- networking support is " |
367 | #ifdef HAVE_NETWORK | 374 | #ifdef HAVE_NETWORK |
368 | "enabled" | 375 | "enabled" |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index c791913ea..efeda7228 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -281,6 +281,9 @@ extern int arg_overlay; // overlay option | |||
281 | extern int arg_overlay_keep; // place overlay diff in a known directory | 281 | extern int arg_overlay_keep; // place overlay diff in a known directory |
282 | extern int arg_overlay_reuse; // allow the reuse of overlays | 282 | extern int arg_overlay_reuse; // allow the reuse of overlays |
283 | 283 | ||
284 | extern int arg_landlock; // add basic Landlock rules | ||
285 | extern int arg_landlock_proc; // 0 - no access; 1 -read-only; 2 - read-write | ||
286 | |||
284 | extern int arg_seccomp; // enable default seccomp filter | 287 | extern int arg_seccomp; // enable default seccomp filter |
285 | extern int arg_seccomp32; // enable default seccomp filter for 32 bit arch | 288 | extern int arg_seccomp32; // enable default seccomp filter for 32 bit arch |
286 | extern int arg_seccomp_postexec; // need postexec ld.preload library? | 289 | extern int arg_seccomp_postexec; // need postexec ld.preload library? |
@@ -950,4 +953,23 @@ void run_ids(int argc, char **argv); | |||
950 | // oom.c | 953 | // oom.c |
951 | void oom_set(const char *oom_string); | 954 | void oom_set(const char *oom_string); |
952 | 955 | ||
956 | // landlock.c | ||
957 | #ifdef HAVE_LANDLOCK | ||
958 | int ll_get_fd(void); | ||
959 | int ll_read(const char *allowed_path); | ||
960 | int ll_write(const char *allowed_path); | ||
961 | int ll_special(const char *allowed_path); | ||
962 | int ll_exec(const char *allowed_path); | ||
963 | int ll_basic_system(void); | ||
964 | int ll_restrict(__u32 flags); | ||
965 | #else | ||
966 | static inline int ll_get_fd(void) { return -1; } | ||
967 | static inline int ll_read(...) { return 0; } | ||
968 | static inline int ll_write(...) { return 0; } | ||
969 | static inline int ll_special(...) { return 0; } | ||
970 | static inline int ll_exec(...) { return 0; } | ||
971 | static inline int ll_basic_system(void) { return 0; } | ||
972 | static inline int ll_restrict(...) { return 0; } | ||
973 | #endif /* HAVE_LANDLOCK */ | ||
974 | |||
953 | #endif | 975 | #endif |
diff --git a/src/firejail/landlock.c b/src/firejail/landlock.c new file mode 100644 index 000000000..b5f4140c5 --- /dev/null +++ b/src/firejail/landlock.c | |||
@@ -0,0 +1,263 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2023 Firejail Authors | ||
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 | #ifdef HAVE_LANDLOCK | ||
22 | #include "firejail.h" | ||
23 | #include <linux/landlock.h> | ||
24 | #include <sys/prctl.h> | ||
25 | #include <sys/syscall.h> | ||
26 | #include <sys/types.h> | ||
27 | #include <errno.h> | ||
28 | #include <fcntl.h> | ||
29 | |||
30 | static int ll_ruleset_fd = -1; | ||
31 | |||
32 | int ll_get_fd(void) { | ||
33 | return ll_ruleset_fd; | ||
34 | } | ||
35 | |||
36 | #ifndef landlock_create_ruleset | ||
37 | static inline int | ||
38 | landlock_create_ruleset(const struct landlock_ruleset_attr *const attr, | ||
39 | const size_t size, const __u32 flags) { | ||
40 | return syscall(__NR_landlock_create_ruleset, attr, size, flags); | ||
41 | } | ||
42 | #endif | ||
43 | |||
44 | #ifndef landlock_add_rule | ||
45 | static inline int | ||
46 | landlock_add_rule(const int ruleset_fd, | ||
47 | const enum landlock_rule_type rule_type, | ||
48 | const void *const rule_attr, | ||
49 | const __u32 flags) { | ||
50 | return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type, | ||
51 | rule_attr, flags); | ||
52 | } | ||
53 | #endif | ||
54 | |||
55 | #ifndef landlock_restrict_self | ||
56 | static inline int | ||
57 | landlock_restrict_self(const int ruleset_fd, const __u32 flags) { | ||
58 | return syscall(__NR_landlock_restrict_self, ruleset_fd, flags); | ||
59 | } | ||
60 | #endif | ||
61 | |||
62 | static int ll_create_full_ruleset() { | ||
63 | struct landlock_ruleset_attr attr; | ||
64 | attr.handled_access_fs = | ||
65 | LANDLOCK_ACCESS_FS_EXECUTE | | ||
66 | LANDLOCK_ACCESS_FS_MAKE_BLOCK | | ||
67 | LANDLOCK_ACCESS_FS_MAKE_CHAR | | ||
68 | LANDLOCK_ACCESS_FS_MAKE_DIR | | ||
69 | LANDLOCK_ACCESS_FS_MAKE_FIFO | | ||
70 | LANDLOCK_ACCESS_FS_MAKE_REG | | ||
71 | LANDLOCK_ACCESS_FS_MAKE_SOCK | | ||
72 | LANDLOCK_ACCESS_FS_MAKE_SYM | | ||
73 | LANDLOCK_ACCESS_FS_READ_DIR | | ||
74 | LANDLOCK_ACCESS_FS_READ_FILE | | ||
75 | LANDLOCK_ACCESS_FS_REMOVE_DIR | | ||
76 | LANDLOCK_ACCESS_FS_REMOVE_FILE | | ||
77 | LANDLOCK_ACCESS_FS_WRITE_FILE; | ||
78 | |||
79 | ll_ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); | ||
80 | if (ll_ruleset_fd < 0) { | ||
81 | fprintf(stderr, "Error: failed to create a Landlock ruleset: %s\n", | ||
82 | strerror(errno)); | ||
83 | } | ||
84 | return ll_ruleset_fd; | ||
85 | } | ||
86 | |||
87 | int ll_read(const char *allowed_path) { | ||
88 | if (ll_ruleset_fd == -1) | ||
89 | ll_ruleset_fd = ll_create_full_ruleset(); | ||
90 | |||
91 | int error; | ||
92 | int allowed_fd = open(allowed_path, O_PATH | O_CLOEXEC); | ||
93 | if (allowed_fd < 0) { | ||
94 | if (arg_debug) { | ||
95 | fprintf(stderr, "%s: failed to open %s: %s\n", | ||
96 | __func__, allowed_path, strerror(errno)); | ||
97 | } | ||
98 | return 0; | ||
99 | } | ||
100 | struct landlock_path_beneath_attr target; | ||
101 | target.parent_fd = allowed_fd; | ||
102 | target.allowed_access = | ||
103 | LANDLOCK_ACCESS_FS_READ_DIR | | ||
104 | LANDLOCK_ACCESS_FS_READ_FILE; | ||
105 | |||
106 | error = landlock_add_rule(ll_ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, | ||
107 | &target, 0); | ||
108 | if (error) { | ||
109 | fprintf(stderr, "Error: %s: failed to add Landlock rule for %s: %s\n", | ||
110 | __func__, allowed_path, strerror(errno)); | ||
111 | } | ||
112 | close(allowed_fd); | ||
113 | return error; | ||
114 | } | ||
115 | |||
116 | int ll_write(const char *allowed_path) { | ||
117 | if (ll_ruleset_fd == -1) | ||
118 | ll_ruleset_fd = ll_create_full_ruleset(); | ||
119 | |||
120 | int error; | ||
121 | int allowed_fd = open(allowed_path, O_PATH | O_CLOEXEC); | ||
122 | if (allowed_fd < 0) { | ||
123 | if (arg_debug) { | ||
124 | fprintf(stderr, "%s: failed to open %s: %s\n", | ||
125 | __func__, allowed_path, strerror(errno)); | ||
126 | } | ||
127 | return 0; | ||
128 | } | ||
129 | struct landlock_path_beneath_attr target; | ||
130 | target.parent_fd = allowed_fd; | ||
131 | target.allowed_access = | ||
132 | LANDLOCK_ACCESS_FS_MAKE_DIR | | ||
133 | LANDLOCK_ACCESS_FS_MAKE_REG | | ||
134 | LANDLOCK_ACCESS_FS_MAKE_SYM | | ||
135 | LANDLOCK_ACCESS_FS_REMOVE_DIR | | ||
136 | LANDLOCK_ACCESS_FS_REMOVE_FILE | | ||
137 | LANDLOCK_ACCESS_FS_WRITE_FILE; | ||
138 | |||
139 | error = landlock_add_rule(ll_ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, | ||
140 | &target, 0); | ||
141 | if (error) { | ||
142 | fprintf(stderr, "Error: %s: failed to add Landlock rule for %s: %s\n", | ||
143 | __func__, allowed_path, strerror(errno)); | ||
144 | } | ||
145 | close(allowed_fd); | ||
146 | return error; | ||
147 | } | ||
148 | |||
149 | int ll_special(const char *allowed_path) { | ||
150 | if (ll_ruleset_fd == -1) | ||
151 | ll_ruleset_fd = ll_create_full_ruleset(); | ||
152 | |||
153 | int error; | ||
154 | int allowed_fd = open(allowed_path, O_PATH | O_CLOEXEC); | ||
155 | if (allowed_fd < 0) { | ||
156 | if (arg_debug) { | ||
157 | fprintf(stderr, "%s: failed to open %s: %s\n", | ||
158 | __func__, allowed_path, strerror(errno)); | ||
159 | } | ||
160 | return 0; | ||
161 | } | ||
162 | struct landlock_path_beneath_attr target; | ||
163 | target.parent_fd = allowed_fd; | ||
164 | target.allowed_access = | ||
165 | LANDLOCK_ACCESS_FS_MAKE_BLOCK | | ||
166 | LANDLOCK_ACCESS_FS_MAKE_CHAR | | ||
167 | LANDLOCK_ACCESS_FS_MAKE_FIFO | | ||
168 | LANDLOCK_ACCESS_FS_MAKE_SOCK; | ||
169 | |||
170 | error = landlock_add_rule(ll_ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, | ||
171 | &target, 0); | ||
172 | if (error) { | ||
173 | fprintf(stderr, "Error: %s: failed to add Landlock rule for %s: %s\n", | ||
174 | __func__, allowed_path, strerror(errno)); | ||
175 | } | ||
176 | close(allowed_fd); | ||
177 | return error; | ||
178 | } | ||
179 | |||
180 | int ll_exec(const char *allowed_path) { | ||
181 | if (ll_ruleset_fd == -1) | ||
182 | ll_ruleset_fd = ll_create_full_ruleset(); | ||
183 | |||
184 | int error; | ||
185 | int allowed_fd = open(allowed_path, O_PATH | O_CLOEXEC); | ||
186 | if (allowed_fd < 0) { | ||
187 | if (arg_debug) { | ||
188 | fprintf(stderr, "%s: failed to open %s: %s\n", | ||
189 | __func__, allowed_path, strerror(errno)); | ||
190 | } | ||
191 | return 0; | ||
192 | } | ||
193 | struct landlock_path_beneath_attr target; | ||
194 | target.parent_fd = allowed_fd; | ||
195 | target.allowed_access = | ||
196 | LANDLOCK_ACCESS_FS_EXECUTE; | ||
197 | |||
198 | error = landlock_add_rule(ll_ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, | ||
199 | &target, 0); | ||
200 | if (error) { | ||
201 | fprintf(stderr, "Error: %s: failed to add Landlock rule for %s: %s\n", | ||
202 | __func__, allowed_path, strerror(errno)); | ||
203 | } | ||
204 | close(allowed_fd); | ||
205 | return error; | ||
206 | } | ||
207 | |||
208 | int ll_basic_system(void) { | ||
209 | assert(cfg.homedir); | ||
210 | |||
211 | if (ll_ruleset_fd == -1) | ||
212 | ll_ruleset_fd = ll_create_full_ruleset(); | ||
213 | |||
214 | int error = | ||
215 | ll_read("/bin/") || | ||
216 | ll_read("/dev/") || | ||
217 | ll_read("/etc/") || | ||
218 | ll_read("/lib/") || | ||
219 | ll_read("/opt/") || | ||
220 | ll_read("/usr/") || | ||
221 | ll_read("/var/") || | ||
222 | ll_read(cfg.homedir) || | ||
223 | |||
224 | ll_write("/dev/") || | ||
225 | ll_write(cfg.homedir) || | ||
226 | |||
227 | ll_exec("/bin/") || | ||
228 | ll_exec("/lib/") || | ||
229 | ll_exec("/opt/") || | ||
230 | ll_exec("/usr/"); | ||
231 | |||
232 | if (error) { | ||
233 | fprintf(stderr, "Error: %s: failed to set --landlock rules\n", | ||
234 | __func__); | ||
235 | } | ||
236 | return error; | ||
237 | } | ||
238 | |||
239 | int ll_restrict(__u32 flags) { | ||
240 | if (ll_ruleset_fd == -1) | ||
241 | return 0; | ||
242 | |||
243 | int error; | ||
244 | error = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | ||
245 | if (error) { | ||
246 | fprintf(stderr, "Error: %s: failed to restrict privileges: %s\n", | ||
247 | __func__, strerror(errno)); | ||
248 | goto out; | ||
249 | } | ||
250 | error = landlock_restrict_self(ll_ruleset_fd, flags); | ||
251 | if (error) { | ||
252 | fprintf(stderr, "Error: %s: failed to enforce Landlock: %s\n", | ||
253 | __func__, strerror(errno)); | ||
254 | goto out; | ||
255 | } | ||
256 | if (arg_debug) | ||
257 | printf("%s: Enforcing Landlock\n", __func__); | ||
258 | out: | ||
259 | close(ll_ruleset_fd); | ||
260 | return error; | ||
261 | } | ||
262 | |||
263 | #endif /* HAVE_LANDLOCK */ | ||
diff --git a/src/firejail/main.c b/src/firejail/main.c index 0c9c80137..df31fe2ce 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -75,6 +75,9 @@ int arg_overlay = 0; // overlay option | |||
75 | int arg_overlay_keep = 0; // place overlay diff in a known directory | 75 | int arg_overlay_keep = 0; // place overlay diff in a known directory |
76 | int arg_overlay_reuse = 0; // allow the reuse of overlays | 76 | int arg_overlay_reuse = 0; // allow the reuse of overlays |
77 | 77 | ||
78 | int arg_landlock = 0; // add basic Landlock rules | ||
79 | int arg_landlock_proc = 2; // 0 - no access; 1 -read-only; 2 - read-write | ||
80 | |||
78 | int arg_seccomp = 0; // enable default seccomp filter | 81 | int arg_seccomp = 0; // enable default seccomp filter |
79 | int arg_seccomp32 = 0; // enable default seccomp filter for 32 bit arch | 82 | int arg_seccomp32 = 0; // enable default seccomp filter for 32 bit arch |
80 | int arg_seccomp_postexec = 0; // need postexec ld.preload library? | 83 | int arg_seccomp_postexec = 0; // need postexec ld.preload library? |
@@ -1500,6 +1503,31 @@ int main(int argc, char **argv, char **envp) { | |||
1500 | else | 1503 | else |
1501 | exit_err_feature("seccomp"); | 1504 | exit_err_feature("seccomp"); |
1502 | } | 1505 | } |
1506 | #ifdef HAVE_LANDLOCK | ||
1507 | else if (strcmp(argv[i], "--landlock") == 0) | ||
1508 | arg_landlock = 1; | ||
1509 | else if (strncmp(argv[i], "--landlock.proc=", 16) == 0) { | ||
1510 | if (strncmp(argv[i] + 16, "no", 2) == 0) | ||
1511 | arg_landlock_proc = 0; | ||
1512 | else if (strncmp(argv[i] + 16, "ro", 2) == 0) | ||
1513 | arg_landlock_proc = 1; | ||
1514 | else if (strncmp(argv[i] + 16, "rw", 2) == 0) | ||
1515 | arg_landlock_proc = 2; | ||
1516 | else { | ||
1517 | fprintf(stderr, "Error: invalid landlock.proc value: %s\n", | ||
1518 | argv[i] + 16); | ||
1519 | exit(1); | ||
1520 | } | ||
1521 | } | ||
1522 | else if (strncmp(argv[i], "--landlock.read=", 16) == 0) | ||
1523 | ll_read(argv[i] + 16); | ||
1524 | else if (strncmp(argv[i], "--landlock.write=", 17) == 0) | ||
1525 | ll_write(argv[i] + 17); | ||
1526 | else if (strncmp(argv[i], "--landlock.special=", 19) == 0) | ||
1527 | ll_special(argv[i] + 19); | ||
1528 | else if (strncmp(argv[i], "--landlock.execute=", 19) == 0) | ||
1529 | ll_exec(argv[i] + 19); | ||
1530 | #endif | ||
1503 | else if (strcmp(argv[i], "--memory-deny-write-execute") == 0) { | 1531 | else if (strcmp(argv[i], "--memory-deny-write-execute") == 0) { |
1504 | if (checkcfg(CFG_SECCOMP)) | 1532 | if (checkcfg(CFG_SECCOMP)) |
1505 | arg_memory_deny_write_execute = 1; | 1533 | arg_memory_deny_write_execute = 1; |
diff --git a/src/firejail/profile.c b/src/firejail/profile.c index a250e5611..08804c5f3 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c | |||
@@ -1077,6 +1077,44 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
1077 | return 0; | 1077 | return 0; |
1078 | } | 1078 | } |
1079 | 1079 | ||
1080 | #ifdef HAVE_LANDLOCK | ||
1081 | // Landlock ruleset paths | ||
1082 | if (strcmp(ptr, "landlock") == 0) { | ||
1083 | arg_landlock = 1; | ||
1084 | return 0; | ||
1085 | } | ||
1086 | if (strncmp(ptr, "landlock.proc ", 14) == 0) { | ||
1087 | if (strncmp(ptr + 14, "no", 2) == 0) | ||
1088 | arg_landlock_proc = 0; | ||
1089 | else if (strncmp(ptr + 14, "ro", 2) == 0) | ||
1090 | arg_landlock_proc = 1; | ||
1091 | else if (strncmp(ptr + 14, "rw", 2) == 0) | ||
1092 | arg_landlock_proc = 2; | ||
1093 | else { | ||
1094 | fprintf(stderr, "Error: invalid landlock.proc value: %s\n", | ||
1095 | ptr + 14); | ||
1096 | exit(1); | ||
1097 | } | ||
1098 | return 0; | ||
1099 | } | ||
1100 | if (strncmp(ptr, "landlock.read ", 14) == 0) { | ||
1101 | ll_read(ptr + 14); | ||
1102 | return 0; | ||
1103 | } | ||
1104 | if (strncmp(ptr, "landlock.write ", 15) == 0) { | ||
1105 | ll_write(ptr + 15); | ||
1106 | return 0; | ||
1107 | } | ||
1108 | if (strncmp(ptr, "landlock.special ", 17) == 0) { | ||
1109 | ll_special(ptr + 17); | ||
1110 | return 0; | ||
1111 | } | ||
1112 | if (strncmp(ptr, "landlock.execute ", 17) == 0) { | ||
1113 | ll_exec(ptr + 17); | ||
1114 | return 0; | ||
1115 | } | ||
1116 | #endif | ||
1117 | |||
1080 | // memory deny write&execute | 1118 | // memory deny write&execute |
1081 | if (strcmp(ptr, "memory-deny-write-execute") == 0) { | 1119 | if (strcmp(ptr, "memory-deny-write-execute") == 0) { |
1082 | if (checkcfg(CFG_SECCOMP)) | 1120 | if (checkcfg(CFG_SECCOMP)) |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 827be5d85..dbc115137 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -516,6 +516,28 @@ void start_application(int no_sandbox, int fd, char *set_sandbox_status) { | |||
516 | printf("LD_PRELOAD=%s\n", getenv("LD_PRELOAD")); | 516 | printf("LD_PRELOAD=%s\n", getenv("LD_PRELOAD")); |
517 | } | 517 | } |
518 | 518 | ||
519 | #ifdef HAVE_LANDLOCK | ||
520 | //**************************** | ||
521 | // Configure Landlock | ||
522 | //**************************** | ||
523 | if (arg_landlock) | ||
524 | ll_basic_system(); | ||
525 | |||
526 | if (ll_get_fd() != -1) { | ||
527 | if (arg_landlock_proc >= 1) | ||
528 | ll_read("/proc/"); | ||
529 | if (arg_landlock_proc == 2) | ||
530 | ll_write("/proc/"); | ||
531 | } | ||
532 | |||
533 | if (ll_restrict(0)) { | ||
534 | // It isn't safe to continue if Landlock self-restriction was | ||
535 | // enabled and the "landlock_restrict_self" syscall has failed. | ||
536 | fprintf(stderr, "Error: ll_restrict() failed, exiting...\n"); | ||
537 | exit(1); | ||
538 | } | ||
539 | #endif | ||
540 | |||
519 | if (just_run_the_shell) { | 541 | if (just_run_the_shell) { |
520 | char *arg[2]; | 542 | char *arg[2]; |
521 | arg[0] = cfg.usershell; | 543 | arg[0] = cfg.usershell; |
diff --git a/src/firejail/usage.c b/src/firejail/usage.c index e8758c807..5f9185da9 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c | |||
@@ -133,6 +133,14 @@ static const char *const usage_str = | |||
133 | " --keep-fd - inherit open file descriptors to sandbox.\n" | 133 | " --keep-fd - inherit open file descriptors to sandbox.\n" |
134 | " --keep-shell-rc - do not copy shell rc files from /etc/skel\n" | 134 | " --keep-shell-rc - do not copy shell rc files from /etc/skel\n" |
135 | " --keep-var-tmp - /var/tmp directory is untouched.\n" | 135 | " --keep-var-tmp - /var/tmp directory is untouched.\n" |
136 | #ifdef HAVE_LANDLOCK | ||
137 | " --landlock - add basic rules to the Landlock ruleset.\n" | ||
138 | " --landlock.proc=no|ro|rw - add an access rule for /proc to the Landlock ruleset.\n" | ||
139 | " --landlock.read=path - add a read access rule for the path to the Landlock ruleset.\n" | ||
140 | " --landlock.write=path - add a write access rule for the path to the Landlock ruleset.\n" | ||
141 | " --landlock.special=path - add an access rule for the path to the Landlock ruleset for creating block/char devices, named pipes and sockets.\n" | ||
142 | " --landlock.execute=path - add an execute access rule for the path to the Landlock ruleset.\n" | ||
143 | #endif | ||
136 | " --list - list all sandboxes.\n" | 144 | " --list - list all sandboxes.\n" |
137 | #ifdef HAVE_FILE_TRANSFER | 145 | #ifdef HAVE_FILE_TRANSFER |
138 | " --ls=name|pid dir_or_filename - list files in sandbox container.\n" | 146 | " --ls=name|pid dir_or_filename - list files in sandbox container.\n" |
diff --git a/src/firejail/util.c b/src/firejail/util.c index bd32181b5..c0f30931c 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -1338,6 +1338,13 @@ void close_all(int *keep_list, size_t sz) { | |||
1338 | if (keep) | 1338 | if (keep) |
1339 | continue; | 1339 | continue; |
1340 | 1340 | ||
1341 | #ifdef HAVE_LANDLOCK | ||
1342 | // Don't close the file descriptor of the Landlock ruleset; it | ||
1343 | // will be automatically closed by the "ll_restrict" wrapper | ||
1344 | // function. | ||
1345 | if (fd == ll_get_fd()) | ||
1346 | continue; | ||
1347 | #endif | ||
1341 | close(fd); | 1348 | close(fd); |
1342 | } | 1349 | } |
1343 | closedir(dir); | 1350 | closedir(dir); |
diff --git a/src/man/firejail-profile.5.in b/src/man/firejail-profile.5.in index 3a678b14f..76f5e4d20 100644 --- a/src/man/firejail-profile.5.in +++ b/src/man/firejail-profile.5.in | |||
@@ -507,6 +507,37 @@ Blacklist all Linux capabilities. | |||
507 | .TP | 507 | .TP |
508 | \fBcaps.keep capability,capability,capability | 508 | \fBcaps.keep capability,capability,capability |
509 | Whitelist given Linux capabilities. | 509 | Whitelist given Linux capabilities. |
510 | #ifdef HAVE_LANDLOCK | ||
511 | .TP | ||
512 | \fBlandlock | ||
513 | Create a Landlock ruleset (if it doesn't already exist) and add basic access | ||
514 | rules to it. | ||
515 | .TP | ||
516 | \fBlandlock.proc no|ro|rw | ||
517 | Add an access rule for /proc directory (read-only if set to \fBro\fR and | ||
518 | read-write if set to \fBrw\fR). | ||
519 | The access rule for /proc is added after this directory is set up in the | ||
520 | sandbox. | ||
521 | Access rules for /proc set up with other Landlock-related profile options have | ||
522 | no effect. | ||
523 | .TP | ||
524 | \fBlandlock.read path | ||
525 | Create a Landlock ruleset (if it doesn't already exist) and add a read access | ||
526 | rule for path. | ||
527 | .TP | ||
528 | \fBlandlock.write path | ||
529 | Create a Landlock ruleset (if it doesn't already exist) and add a write access | ||
530 | rule for path. | ||
531 | .TP | ||
532 | \fBlandlock.special path | ||
533 | Create a Landlock ruleset (if it doesn't already exist) and add a rule that | ||
534 | allows the creation of block devices, character devices, named pipes (FIFOs) | ||
535 | and Unix domain sockets beneath given path. | ||
536 | .TP | ||
537 | \fBlandlock.execute path | ||
538 | Create a Landlock ruleset (if it doesn't already exist) and add an execution | ||
539 | permission rule for path. | ||
540 | #endif | ||
510 | .TP | 541 | .TP |
511 | \fBmemory-deny-write-execute | 542 | \fBmemory-deny-write-execute |
512 | Install a seccomp filter to block attempts to create memory mappings | 543 | Install a seccomp filter to block attempts to create memory mappings |
diff --git a/src/man/firejail.1.in b/src/man/firejail.1.in index 06969e851..d5a00c41b 100644 --- a/src/man/firejail.1.in +++ b/src/man/firejail.1.in | |||
@@ -1243,6 +1243,52 @@ Example: | |||
1243 | .br | 1243 | .br |
1244 | $ firejail --keep-var-tmp | 1244 | $ firejail --keep-var-tmp |
1245 | 1245 | ||
1246 | #ifdef HAVE_LANDLOCK | ||
1247 | .TP | ||
1248 | \fB\-\-landlock | ||
1249 | Create a Landlock ruleset (if it doesn't already exist) and add basic access | ||
1250 | rules to it. | ||
1251 | The basic set of rules applies the following access permissions: | ||
1252 | .PP | ||
1253 | .RS | ||
1254 | - read: /bin, /dev, /etc, /lib, /opt, /proc, /usr, /var | ||
1255 | .br | ||
1256 | - write: /dev, /proc | ||
1257 | .br | ||
1258 | - exec: /bin, /lib, /opt, /usr | ||
1259 | .RE | ||
1260 | .PP | ||
1261 | See the \fBLANDLOCK\fR section for more information. | ||
1262 | .TP | ||
1263 | \fB\-\-landlock.proc=no|ro|rw | ||
1264 | Add an access rule for /proc directory (read-only if set to \fBro\fR and | ||
1265 | read-write if set to \fBrw\fR). | ||
1266 | The access rule for /proc is added after this directory is set up in the | ||
1267 | sandbox. | ||
1268 | Access rules for /proc set up with other Landlock-related command-line options | ||
1269 | have no effect. | ||
1270 | .TP | ||
1271 | \fB\-\-landlock.read=path | ||
1272 | Create a Landlock ruleset (if it doesn't already exist) and add a read access | ||
1273 | rule for path. | ||
1274 | .TP | ||
1275 | \fB\-\-landlock.write=path | ||
1276 | Create a Landlock ruleset (if it doesn't already exist) and add a write access | ||
1277 | rule for path. | ||
1278 | .TP | ||
1279 | \fB\-\-landlock.special=path | ||
1280 | Create a Landlock ruleset (if it doesn't already exist) and add a rule that | ||
1281 | allows the creation of block devices, character devices, named pipes (FIFOs) | ||
1282 | and Unix domain sockets beneath given path. | ||
1283 | .TP | ||
1284 | \fB\-\-landlock.execute=path | ||
1285 | Create a Landlock ruleset (if it doesn't already exist) and add an execution | ||
1286 | permission rule for path. | ||
1287 | .PP | ||
1288 | Example: | ||
1289 | .PP | ||
1290 | $ firejail \-\-landlock.read=/ \-\-landlock.write=/home \-\-landlock.execute=/usr | ||
1291 | #endif | ||
1246 | .TP | 1292 | .TP |
1247 | \fB\-\-list | 1293 | \fB\-\-list |
1248 | List all sandboxes, see \fBMONITORING\fR section for more details. | 1294 | List all sandboxes, see \fBMONITORING\fR section for more details. |
@@ -3365,6 +3411,47 @@ To enable AppArmor confinement on top of your current Firejail security features | |||
3365 | $ firejail --apparmor firefox | 3411 | $ firejail --apparmor firefox |
3366 | #endif | 3412 | #endif |
3367 | 3413 | ||
3414 | #ifdef HAVE_LANDLOCK | ||
3415 | .SH LANDLOCK | ||
3416 | Landlock is a Linux security module first introduced in version 5.13 of the | ||
3417 | Linux kernel. | ||
3418 | It allows unprivileged processes to restrict their access to the filesystem. | ||
3419 | Once imposed, these restrictions can never be removed, and all child processes | ||
3420 | created by a Landlock-restricted processes inherit these restrictions. | ||
3421 | Firejail supports Landlock as an additional sandboxing feature. | ||
3422 | It can be used to ensure that a sandboxed application can only access files and | ||
3423 | directories that it was explicitly allowed to access. | ||
3424 | Firejail supports populating the ruleset with both a basic set of rules (see | ||
3425 | \fB\-\-landlock\fR) and with a custom set of rules. | ||
3426 | .TP | ||
3427 | Important notes: | ||
3428 | .PP | ||
3429 | .RS | ||
3430 | - A process can install a Landlock ruleset only if it has either | ||
3431 | \fBCAP_SYS_ADMIN\fR in its effective capability set, or the "No New | ||
3432 | Privileges" restriction enabled. | ||
3433 | Because of this, enabling the Landlock feature will also cause Firejail to | ||
3434 | enable the "No New Privileges" restriction, regardless of the profile or the | ||
3435 | \fB\-\-no\-new\-privs\fR command line option. | ||
3436 | .PP | ||
3437 | - Access to the /proc directory is managed through the \fB\-\-landlock.proc\fR | ||
3438 | command line option. | ||
3439 | .PP | ||
3440 | - Access to the /etc directory is automatically allowed. | ||
3441 | To override this, use the \fB\-\-writable\-etc\fR command line option. | ||
3442 | You can also use the \fB\-\-private\-etc\fR option to restrict access to the | ||
3443 | /etc directory. | ||
3444 | .RE | ||
3445 | .PP | ||
3446 | To enable Landlock self-restriction on top of your current Firejail security | ||
3447 | features, pass \fB\-\-landlock\fR flag to Firejail command line. | ||
3448 | You can also use \fB\-\-landlock.read\fR, \fB\-\-landlock.write\fR, | ||
3449 | \fB\-\-landlock.special\fR and \fB\-\-landlock.execute\fR options together with | ||
3450 | \fB\-\-landlock\fR or instead of it. | ||
3451 | Example: | ||
3452 | .PP | ||
3453 | $ firejail \-\-landlock \-\-landlock.read=/media \-\-landlock.proc=ro mc | ||
3454 | #endif | ||
3368 | .SH DESKTOP INTEGRATION | 3455 | .SH DESKTOP INTEGRATION |
3369 | A symbolic link to /usr/bin/firejail under the name of a program, will start the program in Firejail sandbox. | 3456 | A symbolic link to /usr/bin/firejail under the name of a program, will start the program in Firejail sandbox. |
3370 | The symbolic link should be placed in the first $PATH position. On most systems, a good place | 3457 | The symbolic link should be placed in the first $PATH position. On most systems, a good place |
diff --git a/src/zsh_completion/_firejail.in b/src/zsh_completion/_firejail.in index 7e87bb991..89cb1b84c 100644 --- a/src/zsh_completion/_firejail.in +++ b/src/zsh_completion/_firejail.in | |||
@@ -106,6 +106,11 @@ _firejail_args=( | |||
106 | '--keep-fd[inherit open file descriptors to sandbox]: :' | 106 | '--keep-fd[inherit open file descriptors to sandbox]: :' |
107 | '--keep-shell-rc[do not copy shell rc files from /etc/skel]' | 107 | '--keep-shell-rc[do not copy shell rc files from /etc/skel]' |
108 | '--keep-var-tmp[/var/tmp directory is untouched]' | 108 | '--keep-var-tmp[/var/tmp directory is untouched]' |
109 | '--landlock.proc=-[add an access rule for /proc to the Landlock ruleset]: :(no ro rw)' | ||
110 | '--landlock.read=-[add a read access rule for the path to the Landlock ruleset]: :_files' | ||
111 | '--landlock.write=-[add a write access rule for the path to the Landlock ruleset]: :_files' | ||
112 | '--landlock.special=-[add an access rule for the path to the Landlock ruleset for creating block/char devices, named pipes and sockets]: :_files' | ||
113 | '--landlock.execute=-[add an execute access rule for the path to the Landlock ruleset]: :_files' | ||
109 | '--machine-id[spoof /etc/machine-id with a random id]' | 114 | '--machine-id[spoof /etc/machine-id with a random id]' |
110 | '--memory-deny-write-execute[seccomp filter to block attempts to create memory mappings that are both writable and executable]' | 115 | '--memory-deny-write-execute[seccomp filter to block attempts to create memory mappings that are both writable and executable]' |
111 | '*--mkdir=-[create a directory]:' | 116 | '*--mkdir=-[create a directory]:' |