aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@protonmail.com>2023-12-04 09:18:05 -0500
committerLibravatar GitHub <noreply@github.com>2023-12-04 09:18:05 -0500
commit9ba5c8d50b2b00244cb539809f8da7ba32043fa4 (patch)
treeff28ac831ce0d11591b2c49f66ee9b92ae1c8b8e
parentMerge pull request #6104 from kmk3/ci-enable-sort-py (diff)
parentlandlock: detect support at runtime (diff)
downloadfirejail-9ba5c8d50b2b00244cb539809f8da7ba32043fa4.tar.gz
firejail-9ba5c8d50b2b00244cb539809f8da7ba32043fa4.tar.zst
firejail-9ba5c8d50b2b00244cb539809f8da7ba32043fa4.zip
Merge pull request #6078 from kmk3/landlock_v3
feature: add Landlock support
-rw-r--r--README3
-rw-r--r--config.mk.in2
-rwxr-xr-xconfigure86
-rw-r--r--configure.ac12
-rw-r--r--contrib/syntax/lists/profile_commands_arg0.list1
-rw-r--r--contrib/syntax/lists/profile_commands_arg1.list5
-rw-r--r--src/bash_completion/firejail.bash_completion.in19
-rw-r--r--src/firejail/checkcfg.c7
-rw-r--r--src/firejail/firejail.h37
-rw-r--r--src/firejail/landlock.c361
-rw-r--r--src/firejail/main.c28
-rw-r--r--src/firejail/profile.c41
-rw-r--r--src/firejail/sandbox.c22
-rw-r--r--src/firejail/usage.c8
-rw-r--r--src/firejail/util.c7
-rw-r--r--src/man/firejail-profile.5.in31
-rw-r--r--src/man/firejail.1.in87
-rw-r--r--src/zsh_completion/_firejail.in5
18 files changed, 730 insertions, 32 deletions
diff --git a/README b/README
index 607ce1bee..c9d44d9ed 100644
--- a/README
+++ b/README
@@ -200,7 +200,8 @@ avoidr (https://github.com/avoidr)
200 - fixed mpv profile 200 - fixed mpv profile
201 - various other fixes 201 - various other fixes
202Азалия Смарагдова/ChrysoliteAzalea (https://github.com/ChrysoliteAzalea) 202Азалия Смарагдова/ChrysoliteAzalea (https://github.com/ChrysoliteAzalea)
203 - add support for custom AppArmor profiles (--apparmor=) 203 - add support for custom AppArmor profiles (--apparmor=)
204 - add Landlock support
204backspac (https://github.com/backspac) 205backspac (https://github.com/backspac)
205 - firecfg fixes 206 - firecfg fixes
206 - add steam-runtime alias 207 - 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@
38HAVE_FORCE_NONEWPRIVS=@HAVE_FORCE_NONEWPRIVS@ 38HAVE_FORCE_NONEWPRIVS=@HAVE_FORCE_NONEWPRIVS@
39HAVE_GLOBALCFG=@HAVE_GLOBALCFG@ 39HAVE_GLOBALCFG=@HAVE_GLOBALCFG@
40HAVE_IDS=@HAVE_IDS@ 40HAVE_IDS=@HAVE_IDS@
41HAVE_LANDLOCK=@HAVE_LANDLOCK@
41HAVE_LTS=@HAVE_LTS@ 42HAVE_LTS=@HAVE_LTS@
42HAVE_NETWORK=@HAVE_NETWORK@ 43HAVE_NETWORK=@HAVE_NETWORK@
43HAVE_ONLY_SYSCFG_PROFILES=@HAVE_ONLY_SYSCFG_PROFILES@ 44HAVE_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) \
diff --git a/configure b/configure
index 54b9d4da3..8c2d3b894 100755
--- a/configure
+++ b/configure
@@ -675,6 +675,7 @@ HAVE_OVERLAYFS
675HAVE_DBUSPROXY 675HAVE_DBUSPROXY
676EXTRA_LDFLAGS 676EXTRA_LDFLAGS
677EXTRA_CFLAGS 677EXTRA_CFLAGS
678HAVE_LANDLOCK
678HAVE_SELINUX 679HAVE_SELINUX
679AA_LIBS 680AA_LIBS
680AA_CFLAGS 681AA_CFLAGS
@@ -737,6 +738,7 @@ enable_sanitizer
737enable_ids 738enable_ids
738enable_apparmor 739enable_apparmor
739enable_selinux 740enable_selinux
741enable_landlock
740enable_dbusproxy 742enable_dbusproxy
741enable_output 743enable_output
742enable_usertmpfs 744enable_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
3740fi 3743fi
3741 3744
3745HAVE_LANDLOCK=""
3746
3747# Check whether --enable-landlock was given.
3748if test ${enable_landlock+y}
3749then :
3750 enableval=$enable_landlock;
3751fi
3752
3753ac_header= ac_cache=
3754for ac_item in $ac_header_c_list
3755do
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
3767done
3768
3769
3770
3771
3772
3773
3774
3775
3776if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes
3777then :
3778
3779printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h
3780
3781fi
3782if test "x$enable_landlock" != "xno"
3783then :
3784
3785 ac_fn_c_check_header_compile "$LINENO" "linux/landlock.h" "ac_cv_header_linux_landlock_h" "$ac_includes_default"
3786if test "x$ac_cv_header_linux_landlock_h" = xyes
3787then :
3788 HAVE_LANDLOCK="-DHAVE_LANDLOCK"
3789else $as_nop
3790 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: header not found: linux/landlock.h, building without Landlock support" >&5
3791printf "%s\n" "$as_me: WARNING: header not found: linux/landlock.h, building without Landlock support" >&2;}
3792fi
3793
3794
3795fi
3796
3742 3797
3743 3798
3744 3799
@@ -4112,6 +4167,7 @@ if test "x$enable_lts" = "xyes"
4112then : 4167then :
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
4133fi 4189fi
4134 4190
4135ac_header= ac_cache=
4136for ac_item in $ac_header_c_list
4137do
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
4149done
4150
4151
4152
4153
4154
4155
4156
4157
4158if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes
4159then :
4160
4161printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h
4162
4163fi
4164ac_fn_c_check_header_compile "$LINENO" "linux/seccomp.h" "ac_cv_header_linux_seccomp_h" "$ac_includes_default" 4191ac_fn_c_check_header_compile "$LINENO" "linux/seccomp.h" "ac_cv_header_linux_seccomp_h" "$ac_includes_default"
4165if test "x$ac_cv_header_linux_seccomp_h" = xyes 4192if test "x$ac_cv_header_linux_seccomp_h" = xyes
4166then : 4193then :
@@ -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
84HAVE_LANDLOCK=""
85AC_SUBST([HAVE_LANDLOCK])
86AC_ARG_ENABLE([landlock],
87 [AS_HELP_STRING([--enable-landlock], [Landlock self-restriction support])])
88AS_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
84AC_SUBST([EXTRA_CFLAGS]) 94AC_SUBST([EXTRA_CFLAGS])
85AC_SUBST([EXTRA_LDFLAGS]) 95AC_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)])])
265AS_IF([test "x$enable_lts" = "xyes"], [ 275AS_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
12keep-dev-shm 12keep-dev-shm
13keep-shell-rc 13keep-shell-rc
14keep-var-tmp 14keep-var-tmp
15landlock
15machine-id 16machine-id
16memory-deny-write-execute 17memory-deny-write-execute
17netfilter 18netfilter
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
29iprange 29iprange
30join-or-start 30join-or-start
31keep-fd 31keep-fd
32landlock.execute
33landlock.proc
34landlock.read
35landlock.special
36landlock.write
32mac 37mac
33mkdir 38mkdir
34mkfile 39mkfile
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..5a96fcbfd 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -150,6 +150,17 @@ typedef struct profile_entry_t {
150 150
151} ProfileEntry; 151} ProfileEntry;
152 152
153typedef struct landlock_entry_t {
154 struct landlock_entry_t *next;
155#define LL_READ 0
156#define LL_WRITE 1
157#define LL_SPECIAL 2
158#define LL_EXEC 3
159#define LL_MAX 4
160 int type;
161 char *data;
162} LandlockEntry;
163
153typedef struct config_t { 164typedef struct config_t {
154 // user data 165 // user data
155 char *username; 166 char *username;
@@ -159,6 +170,7 @@ typedef struct config_t {
159 // filesystem 170 // filesystem
160 ProfileEntry *profile; 171 ProfileEntry *profile;
161 ProfileEntry *profile_rebuild_etc; // blacklist files in /etc directory used by fs_rebuild_etc() 172 ProfileEntry *profile_rebuild_etc; // blacklist files in /etc directory used by fs_rebuild_etc()
173 LandlockEntry *lprofile;
162 174
163#define MAX_PROFILE_IGNORE 32 175#define MAX_PROFILE_IGNORE 32
164 char *profile_ignore[MAX_PROFILE_IGNORE]; 176 char *profile_ignore[MAX_PROFILE_IGNORE];
@@ -281,6 +293,9 @@ extern int arg_overlay; // overlay option
281extern int arg_overlay_keep; // place overlay diff in a known directory 293extern int arg_overlay_keep; // place overlay diff in a known directory
282extern int arg_overlay_reuse; // allow the reuse of overlays 294extern int arg_overlay_reuse; // allow the reuse of overlays
283 295
296extern int arg_landlock; // add basic Landlock rules
297extern int arg_landlock_proc; // 0 - no access; 1 -read-only; 2 - read-write
298
284extern int arg_seccomp; // enable default seccomp filter 299extern int arg_seccomp; // enable default seccomp filter
285extern int arg_seccomp32; // enable default seccomp filter for 32 bit arch 300extern int arg_seccomp32; // enable default seccomp filter for 32 bit arch
286extern int arg_seccomp_postexec; // need postexec ld.preload library? 301extern int arg_seccomp_postexec; // need postexec ld.preload library?
@@ -950,4 +965,26 @@ void run_ids(int argc, char **argv);
950// oom.c 965// oom.c
951void oom_set(const char *oom_string); 966void oom_set(const char *oom_string);
952 967
968// landlock.c
969#ifdef HAVE_LANDLOCK
970int ll_get_fd(void);
971int ll_is_supported(void);
972int ll_read(const char *allowed_path);
973int ll_write(const char *allowed_path);
974int ll_special(const char *allowed_path);
975int ll_exec(const char *allowed_path);
976int ll_basic_system(void);
977int ll_restrict(__u32 flags);
978void ll_add_profile(int type, const char *data);
979#else
980static inline int ll_get_fd(void) { return -1; }
981static inline int ll_read(...) { return 0; }
982static inline int ll_write(...) { return 0; }
983static inline int ll_special(...) { return 0; }
984static inline int ll_exec(...) { return 0; }
985static inline int ll_basic_system(void) { return 0; }
986static inline int ll_restrict(...) { return 0; }
987static inline void ll_add_profile(...) { return; }
988#endif /* HAVE_LANDLOCK */
989
953#endif 990#endif
diff --git a/src/firejail/landlock.c b/src/firejail/landlock.c
new file mode 100644
index 000000000..27fc1d748
--- /dev/null
+++ b/src/firejail/landlock.c
@@ -0,0 +1,361 @@
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
30static int ll_ruleset_fd = -1;
31static int ll_abi = -1;
32
33int ll_get_fd(void) {
34 return ll_ruleset_fd;
35}
36
37#ifndef landlock_create_ruleset
38static inline int
39landlock_create_ruleset(const struct landlock_ruleset_attr *const attr,
40 const size_t size, const __u32 flags) {
41 return syscall(__NR_landlock_create_ruleset, attr, size, flags);
42}
43#endif
44
45#ifndef landlock_add_rule
46static inline int
47landlock_add_rule(const int ruleset_fd,
48 const enum landlock_rule_type rule_type,
49 const void *const rule_attr,
50 const __u32 flags) {
51 return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type,
52 rule_attr, flags);
53}
54#endif
55
56#ifndef landlock_restrict_self
57static inline int
58landlock_restrict_self(const int ruleset_fd, const __u32 flags) {
59 return syscall(__NR_landlock_restrict_self, ruleset_fd, flags);
60}
61#endif
62
63int ll_is_supported(void) {
64 if (ll_abi != -1)
65 goto out;
66
67 ll_abi = landlock_create_ruleset(NULL, 0,
68 LANDLOCK_CREATE_RULESET_VERSION);
69 if (ll_abi < 1) {
70 ll_abi = 0;
71 fprintf(stderr, "Warning: Landlock is disabled or not supported: %s, "
72 "ignoring landlock commands\n",
73 strerror(errno));
74 goto out;
75 }
76 if (arg_debug) {
77 printf("Detected Landlock ABI version %d\n", ll_abi);
78 }
79out:
80 return ll_abi;
81}
82
83static int ll_create_full_ruleset() {
84 if (!ll_is_supported())
85 return -1;
86
87 struct landlock_ruleset_attr attr;
88 attr.handled_access_fs =
89 LANDLOCK_ACCESS_FS_EXECUTE |
90 LANDLOCK_ACCESS_FS_MAKE_BLOCK |
91 LANDLOCK_ACCESS_FS_MAKE_CHAR |
92 LANDLOCK_ACCESS_FS_MAKE_DIR |
93 LANDLOCK_ACCESS_FS_MAKE_FIFO |
94 LANDLOCK_ACCESS_FS_MAKE_REG |
95 LANDLOCK_ACCESS_FS_MAKE_SOCK |
96 LANDLOCK_ACCESS_FS_MAKE_SYM |
97 LANDLOCK_ACCESS_FS_READ_DIR |
98 LANDLOCK_ACCESS_FS_READ_FILE |
99 LANDLOCK_ACCESS_FS_REMOVE_DIR |
100 LANDLOCK_ACCESS_FS_REMOVE_FILE |
101 LANDLOCK_ACCESS_FS_WRITE_FILE;
102
103 ll_ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0);
104 if (ll_ruleset_fd < 0) {
105 fprintf(stderr, "Error: failed to create a Landlock ruleset: %s\n",
106 strerror(errno));
107 }
108 return ll_ruleset_fd;
109}
110
111int ll_read(const char *allowed_path) {
112 if (!ll_is_supported())
113 return 0;
114
115 if (ll_ruleset_fd == -1)
116 ll_ruleset_fd = ll_create_full_ruleset();
117
118 int error;
119 int allowed_fd = open(allowed_path, O_PATH | O_CLOEXEC);
120 if (allowed_fd < 0) {
121 if (arg_debug) {
122 fprintf(stderr, "%s: failed to open %s: %s\n",
123 __func__, allowed_path, strerror(errno));
124 }
125 return 0;
126 }
127 struct landlock_path_beneath_attr target;
128 target.parent_fd = allowed_fd;
129 target.allowed_access =
130 LANDLOCK_ACCESS_FS_READ_DIR |
131 LANDLOCK_ACCESS_FS_READ_FILE;
132
133 error = landlock_add_rule(ll_ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
134 &target, 0);
135 if (error) {
136 fprintf(stderr, "Error: %s: failed to add Landlock rule for %s: %s\n",
137 __func__, allowed_path, strerror(errno));
138 }
139 close(allowed_fd);
140 return error;
141}
142
143int ll_write(const char *allowed_path) {
144 if (!ll_is_supported())
145 return 0;
146
147 if (ll_ruleset_fd == -1)
148 ll_ruleset_fd = ll_create_full_ruleset();
149
150 int error;
151 int allowed_fd = open(allowed_path, O_PATH | O_CLOEXEC);
152 if (allowed_fd < 0) {
153 if (arg_debug) {
154 fprintf(stderr, "%s: failed to open %s: %s\n",
155 __func__, allowed_path, strerror(errno));
156 }
157 return 0;
158 }
159 struct landlock_path_beneath_attr target;
160 target.parent_fd = allowed_fd;
161 target.allowed_access =
162 LANDLOCK_ACCESS_FS_MAKE_DIR |
163 LANDLOCK_ACCESS_FS_MAKE_REG |
164 LANDLOCK_ACCESS_FS_MAKE_SYM |
165 LANDLOCK_ACCESS_FS_REMOVE_DIR |
166 LANDLOCK_ACCESS_FS_REMOVE_FILE |
167 LANDLOCK_ACCESS_FS_WRITE_FILE;
168
169 error = landlock_add_rule(ll_ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
170 &target, 0);
171 if (error) {
172 fprintf(stderr, "Error: %s: failed to add Landlock rule for %s: %s\n",
173 __func__, allowed_path, strerror(errno));
174 }
175 close(allowed_fd);
176 return error;
177}
178
179int ll_special(const char *allowed_path) {
180 if (!ll_is_supported())
181 return 0;
182
183 if (ll_ruleset_fd == -1)
184 ll_ruleset_fd = ll_create_full_ruleset();
185
186 int error;
187 int allowed_fd = open(allowed_path, O_PATH | O_CLOEXEC);
188 if (allowed_fd < 0) {
189 if (arg_debug) {
190 fprintf(stderr, "%s: failed to open %s: %s\n",
191 __func__, allowed_path, strerror(errno));
192 }
193 return 0;
194 }
195 struct landlock_path_beneath_attr target;
196 target.parent_fd = allowed_fd;
197 target.allowed_access =
198 LANDLOCK_ACCESS_FS_MAKE_BLOCK |
199 LANDLOCK_ACCESS_FS_MAKE_CHAR |
200 LANDLOCK_ACCESS_FS_MAKE_FIFO |
201 LANDLOCK_ACCESS_FS_MAKE_SOCK;
202
203 error = landlock_add_rule(ll_ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
204 &target, 0);
205 if (error) {
206 fprintf(stderr, "Error: %s: failed to add Landlock rule for %s: %s\n",
207 __func__, allowed_path, strerror(errno));
208 }
209 close(allowed_fd);
210 return error;
211}
212
213int ll_exec(const char *allowed_path) {
214 if (!ll_is_supported())
215 return 0;
216
217 if (ll_ruleset_fd == -1)
218 ll_ruleset_fd = ll_create_full_ruleset();
219
220 int error;
221 int allowed_fd = open(allowed_path, O_PATH | O_CLOEXEC);
222 if (allowed_fd < 0) {
223 if (arg_debug) {
224 fprintf(stderr, "%s: failed to open %s: %s\n",
225 __func__, allowed_path, strerror(errno));
226 }
227 return 0;
228 }
229 struct landlock_path_beneath_attr target;
230 target.parent_fd = allowed_fd;
231 target.allowed_access =
232 LANDLOCK_ACCESS_FS_EXECUTE;
233
234 error = landlock_add_rule(ll_ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
235 &target, 0);
236 if (error) {
237 fprintf(stderr, "Error: %s: failed to add Landlock rule for %s: %s\n",
238 __func__, allowed_path, strerror(errno));
239 }
240 close(allowed_fd);
241 return error;
242}
243
244int ll_basic_system(void) {
245 assert(cfg.homedir);
246
247 if (!ll_is_supported())
248 return 0;
249
250 if (ll_ruleset_fd == -1)
251 ll_ruleset_fd = ll_create_full_ruleset();
252
253 int error;
254 char *rundir;
255 if (asprintf(&rundir, "/run/user/%d", getuid()) == -1)
256 errExit("asprintf");
257
258 error =
259 ll_read("/") || // whole system read
260 ll_special("/") || // sockets etc.
261
262 ll_write("/tmp") || // write access
263 ll_write("/dev") ||
264 ll_write("/run/shm") ||
265 ll_write(cfg.homedir) ||
266 ll_write(rundir) ||
267
268 ll_exec("/opt") || // exec access
269 ll_exec("/bin") ||
270 ll_exec("/sbin") ||
271 ll_exec("/lib") ||
272 ll_exec("/lib32") ||
273 ll_exec("/libx32") ||
274 ll_exec("/lib64") ||
275 ll_exec("/usr/bin") ||
276 ll_exec("/usr/sbin") ||
277 ll_exec("/usr/games") ||
278 ll_exec("/usr/lib") ||
279 ll_exec("/usr/lib32") ||
280 ll_exec("/usr/libx32") ||
281 ll_exec("/usr/lib64") ||
282 ll_exec("/usr/local/bin") ||
283 ll_exec("/usr/local/sbin") ||
284 ll_exec("/usr/local/games") ||
285 ll_exec("/usr/local/lib") ||
286 ll_exec("/run/firejail"); // appimage and various firejail features
287
288 if (error) {
289 fprintf(stderr, "Error: %s: failed to set --landlock rules\n",
290 __func__);
291 }
292 free(rundir);
293 return error;
294}
295
296int ll_restrict(__u32 flags) {
297 if (!ll_is_supported())
298 return 0;
299
300 int (*fnc[])(const char *) = {
301 ll_read,
302 ll_write,
303 ll_special,
304 ll_exec,
305 NULL
306 };
307
308 LandlockEntry *ptr = cfg.lprofile;
309 while (ptr) {
310 fnc[ptr->type](ptr->data);
311 ptr = ptr->next;
312 }
313
314 if (ll_ruleset_fd == -1)
315 return 0;
316
317 int error;
318 error = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
319 if (error) {
320 fprintf(stderr, "Error: %s: failed to restrict privileges: %s\n",
321 __func__, strerror(errno));
322 goto out;
323 }
324 error = landlock_restrict_self(ll_ruleset_fd, flags);
325 if (error) {
326 fprintf(stderr, "Error: %s: failed to enforce Landlock: %s\n",
327 __func__, strerror(errno));
328 goto out;
329 }
330 if (arg_debug)
331 printf("%s: Enforcing Landlock\n", __func__);
332out:
333 close(ll_ruleset_fd);
334 return error;
335}
336
337void ll_add_profile(int type, const char *data) {
338 assert(type >= 0);
339 assert(type < LL_MAX);
340 assert(data);
341
342 if (!ll_is_supported())
343 return;
344
345 const char *str = data;
346 while (*str == ' ' || *str == '\t')
347 str++;
348
349 LandlockEntry *ptr = malloc(sizeof(LandlockEntry));
350 if (!ptr)
351 errExit("malloc");
352 memset(ptr, 0, sizeof(LandlockEntry));
353 ptr->type = type;
354 ptr->data = strdup(str);
355 if (!ptr->data)
356 errExit("strdup");
357 ptr->next = cfg.lprofile;
358 cfg.lprofile = ptr;
359}
360
361#endif /* HAVE_LANDLOCK */
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 0327f8bda..5bcc3a0e5 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -75,6 +75,9 @@ int arg_overlay = 0; // overlay option
75int arg_overlay_keep = 0; // place overlay diff in a known directory 75int arg_overlay_keep = 0; // place overlay diff in a known directory
76int arg_overlay_reuse = 0; // allow the reuse of overlays 76int arg_overlay_reuse = 0; // allow the reuse of overlays
77 77
78int arg_landlock = 0; // add basic Landlock rules
79int arg_landlock_proc = 2; // 0 - no access; 1 -read-only; 2 - read-write
80
78int arg_seccomp = 0; // enable default seccomp filter 81int arg_seccomp = 0; // enable default seccomp filter
79int arg_seccomp32 = 0; // enable default seccomp filter for 32 bit arch 82int arg_seccomp32 = 0; // enable default seccomp filter for 32 bit arch
80int arg_seccomp_postexec = 0; // need postexec ld.preload library? 83int 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_add_profile(LL_READ, argv[i] + 16);
1524 else if (strncmp(argv[i], "--landlock.write=", 17) == 0)
1525 ll_add_profile(LL_WRITE, argv[i] + 17);
1526 else if (strncmp(argv[i], "--landlock.special=", 19) == 0)
1527 ll_add_profile(LL_SPECIAL, argv[i] + 19);
1528 else if (strncmp(argv[i], "--landlock.execute=", 19) == 0)
1529 ll_add_profile(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 0f60e9b7d..62d3c78e7 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -1073,6 +1073,44 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
1073 return 0; 1073 return 0;
1074 } 1074 }
1075 1075
1076#ifdef HAVE_LANDLOCK
1077 // Landlock ruleset paths
1078 if (strcmp(ptr, "landlock") == 0) {
1079 arg_landlock = 1;
1080 return 0;
1081 }
1082 if (strncmp(ptr, "landlock.proc ", 14) == 0) {
1083 if (strncmp(ptr + 14, "no", 2) == 0)
1084 arg_landlock_proc = 0;
1085 else if (strncmp(ptr + 14, "ro", 2) == 0)
1086 arg_landlock_proc = 1;
1087 else if (strncmp(ptr + 14, "rw", 2) == 0)
1088 arg_landlock_proc = 2;
1089 else {
1090 fprintf(stderr, "Error: invalid landlock.proc value: %s\n",
1091 ptr + 14);
1092 exit(1);
1093 }
1094 return 0;
1095 }
1096 if (strncmp(ptr, "landlock.read ", 14) == 0) {
1097 ll_add_profile(LL_READ, ptr + 14);
1098 return 0;
1099 }
1100 if (strncmp(ptr, "landlock.write ", 15) == 0) {
1101 ll_add_profile(LL_WRITE, ptr + 15);
1102 return 0;
1103 }
1104 if (strncmp(ptr, "landlock.special ", 17) == 0) {
1105 ll_add_profile(LL_SPECIAL, ptr + 17);
1106 return 0;
1107 }
1108 if (strncmp(ptr, "landlock.execute ", 17) == 0) {
1109 ll_add_profile(LL_EXEC, ptr + 17);
1110 return 0;
1111 }
1112#endif
1113
1076 // memory deny write&execute 1114 // memory deny write&execute
1077 if (strcmp(ptr, "memory-deny-write-execute") == 0) { 1115 if (strcmp(ptr, "memory-deny-write-execute") == 0) {
1078 if (checkcfg(CFG_SECCOMP)) 1116 if (checkcfg(CFG_SECCOMP))
@@ -1897,8 +1935,7 @@ void profile_read(const char *fname) {
1897 fclose(fp); 1935 fclose(fp);
1898} 1936}
1899 1937
1900char *profile_list_normalize(char *list) 1938char *profile_list_normalize(char *list) {
1901{
1902 /* Remove redundant commas. 1939 /* Remove redundant commas.
1903 * 1940 *
1904 * As result is always shorter than original, 1941 * As result is always shorter than original,
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
509Whitelist given Linux capabilities. 509Whitelist given Linux capabilities.
510#ifdef HAVE_LANDLOCK
511.TP
512\fBlandlock
513Create a Landlock ruleset (if it doesn't already exist) and add basic access
514rules to it.
515.TP
516\fBlandlock.proc no|ro|rw
517Add an access rule for /proc directory (read-only if set to \fBro\fR and
518read-write if set to \fBrw\fR).
519The access rule for /proc is added after this directory is set up in the
520sandbox.
521Access rules for /proc set up with other Landlock-related profile options have
522no effect.
523.TP
524\fBlandlock.read path
525Create a Landlock ruleset (if it doesn't already exist) and add a read access
526rule for path.
527.TP
528\fBlandlock.write path
529Create a Landlock ruleset (if it doesn't already exist) and add a write access
530rule for path.
531.TP
532\fBlandlock.special path
533Create a Landlock ruleset (if it doesn't already exist) and add a rule that
534allows the creation of block devices, character devices, named pipes (FIFOs)
535and Unix domain sockets beneath given path.
536.TP
537\fBlandlock.execute path
538Create a Landlock ruleset (if it doesn't already exist) and add an execution
539permission rule for path.
540#endif
510.TP 541.TP
511\fBmemory-deny-write-execute 542\fBmemory-deny-write-execute
512Install a seccomp filter to block attempts to create memory mappings 543Install 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
1249Create a Landlock ruleset (if it doesn't already exist) and add basic access
1250rules to it.
1251The 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
1261See the \fBLANDLOCK\fR section for more information.
1262.TP
1263\fB\-\-landlock.proc=no|ro|rw
1264Add an access rule for /proc directory (read-only if set to \fBro\fR and
1265read-write if set to \fBrw\fR).
1266The access rule for /proc is added after this directory is set up in the
1267sandbox.
1268Access rules for /proc set up with other Landlock-related command-line options
1269have no effect.
1270.TP
1271\fB\-\-landlock.read=path
1272Create a Landlock ruleset (if it doesn't already exist) and add a read access
1273rule for path.
1274.TP
1275\fB\-\-landlock.write=path
1276Create a Landlock ruleset (if it doesn't already exist) and add a write access
1277rule for path.
1278.TP
1279\fB\-\-landlock.special=path
1280Create a Landlock ruleset (if it doesn't already exist) and add a rule that
1281allows the creation of block devices, character devices, named pipes (FIFOs)
1282and Unix domain sockets beneath given path.
1283.TP
1284\fB\-\-landlock.execute=path
1285Create a Landlock ruleset (if it doesn't already exist) and add an execution
1286permission rule for path.
1287.PP
1288Example:
1289.PP
1290$ firejail \-\-landlock.read=/ \-\-landlock.write=/home \-\-landlock.execute=/usr
1291#endif
1246.TP 1292.TP
1247\fB\-\-list 1293\fB\-\-list
1248List all sandboxes, see \fBMONITORING\fR section for more details. 1294List 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
3416Landlock is a Linux security module first introduced in version 5.13 of the
3417Linux kernel.
3418It allows unprivileged processes to restrict their access to the filesystem.
3419Once imposed, these restrictions can never be removed, and all child processes
3420created by a Landlock-restricted processes inherit these restrictions.
3421Firejail supports Landlock as an additional sandboxing feature.
3422It can be used to ensure that a sandboxed application can only access files and
3423directories that it was explicitly allowed to access.
3424Firejail 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
3427Important 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
3432Privileges" restriction enabled.
3433Because of this, enabling the Landlock feature will also cause Firejail to
3434enable 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
3438command line option.
3439.PP
3440- Access to the /etc directory is automatically allowed.
3441To override this, use the \fB\-\-writable\-etc\fR command line option.
3442You can also use the \fB\-\-private\-etc\fR option to restrict access to the
3443/etc directory.
3444.RE
3445.PP
3446To enable Landlock self-restriction on top of your current Firejail security
3447features, pass \fB\-\-landlock\fR flag to Firejail command line.
3448You 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.
3451Example:
3452.PP
3453$ firejail \-\-landlock \-\-landlock.read=/media \-\-landlock.proc=ro mc
3454#endif
3368.SH DESKTOP INTEGRATION 3455.SH DESKTOP INTEGRATION
3369A symbolic link to /usr/bin/firejail under the name of a program, will start the program in Firejail sandbox. 3456A symbolic link to /usr/bin/firejail under the name of a program, will start the program in Firejail sandbox.
3370The symbolic link should be placed in the first $PATH position. On most systems, a good place 3457The 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]:'