Commit 522667b2 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'landlock-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux

Pull landlock updates from Mickaël Salaün:
 "Improve user help for Landlock (documentation and sample)"

* tag 'landlock-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux:
  landlock: Fix documentation style
  landlock: Slightly improve documentation and fix spelling
  samples/landlock: Print hints about ABI versions
parents c645c11a 2fff00c8
...@@ -7,7 +7,7 @@ Landlock LSM: kernel documentation ...@@ -7,7 +7,7 @@ Landlock LSM: kernel documentation
================================== ==================================
:Author: Mickaël Salaün :Author: Mickaël Salaün
:Date: May 2022 :Date: September 2022
Landlock's goal is to create scoped access-control (i.e. sandboxing). To Landlock's goal is to create scoped access-control (i.e. sandboxing). To
harden a whole system, this feature should be available to any process, harden a whole system, this feature should be available to any process,
...@@ -49,13 +49,13 @@ Filesystem access rights ...@@ -49,13 +49,13 @@ Filesystem access rights
------------------------ ------------------------
All access rights are tied to an inode and what can be accessed through it. All access rights are tied to an inode and what can be accessed through it.
Reading the content of a directory doesn't imply to be allowed to read the Reading the content of a directory does not imply to be allowed to read the
content of a listed inode. Indeed, a file name is local to its parent content of a listed inode. Indeed, a file name is local to its parent
directory, and an inode can be referenced by multiple file names thanks to directory, and an inode can be referenced by multiple file names thanks to
(hard) links. Being able to unlink a file only has a direct impact on the (hard) links. Being able to unlink a file only has a direct impact on the
directory, not the unlinked inode. This is the reason why directory, not the unlinked inode. This is the reason why
`LANDLOCK_ACCESS_FS_REMOVE_FILE` or `LANDLOCK_ACCESS_FS_REFER` are not allowed ``LANDLOCK_ACCESS_FS_REMOVE_FILE`` or ``LANDLOCK_ACCESS_FS_REFER`` are not
to be tied to files but only to directories. allowed to be tied to files but only to directories.
Tests Tests
===== =====
......
...@@ -8,7 +8,7 @@ Landlock: unprivileged access control ...@@ -8,7 +8,7 @@ Landlock: unprivileged access control
===================================== =====================================
:Author: Mickaël Salaün :Author: Mickaël Salaün
:Date: May 2022 :Date: September 2022
The goal of Landlock is to enable to restrict ambient rights (e.g. global The goal of Landlock is to enable to restrict ambient rights (e.g. global
filesystem access) for a set of processes. Because Landlock is a stackable filesystem access) for a set of processes. Because Landlock is a stackable
...@@ -69,7 +69,7 @@ should try to protect users as much as possible whatever the kernel they are ...@@ -69,7 +69,7 @@ should try to protect users as much as possible whatever the kernel they are
using. To avoid binary enforcement (i.e. either all security features or using. To avoid binary enforcement (i.e. either all security features or
none), we can leverage a dedicated Landlock command to get the current version none), we can leverage a dedicated Landlock command to get the current version
of the Landlock ABI and adapt the handled accesses. Let's check if we should of the Landlock ABI and adapt the handled accesses. Let's check if we should
remove the `LANDLOCK_ACCESS_FS_REFER` access right which is only supported remove the ``LANDLOCK_ACCESS_FS_REFER`` access right which is only supported
starting with the second version of the ABI. starting with the second version of the ABI.
.. code-block:: c .. code-block:: c
...@@ -128,7 +128,7 @@ descriptor. ...@@ -128,7 +128,7 @@ descriptor.
It may also be required to create rules following the same logic as explained It may also be required to create rules following the same logic as explained
for the ruleset creation, by filtering access rights according to the Landlock for the ruleset creation, by filtering access rights according to the Landlock
ABI version. In this example, this is not required because ABI version. In this example, this is not required because
`LANDLOCK_ACCESS_FS_REFER` is not allowed by any rule. ``LANDLOCK_ACCESS_FS_REFER`` is not allowed by any rule.
We now have a ruleset with one rule allowing read access to ``/usr`` while We now have a ruleset with one rule allowing read access to ``/usr`` while
denying all other handled accesses for the filesystem. The next step is to denying all other handled accesses for the filesystem. The next step is to
...@@ -154,8 +154,8 @@ The current thread is now ready to sandbox itself with the ruleset. ...@@ -154,8 +154,8 @@ The current thread is now ready to sandbox itself with the ruleset.
} }
close(ruleset_fd); close(ruleset_fd);
If the `landlock_restrict_self` system call succeeds, the current thread is now If the ``landlock_restrict_self`` system call succeeds, the current thread is
restricted and this policy will be enforced on all its subsequently created now restricted and this policy will be enforced on all its subsequently created
children as well. Once a thread is landlocked, there is no way to remove its children as well. Once a thread is landlocked, there is no way to remove its
security policy; only adding more restrictions is allowed. These threads are security policy; only adding more restrictions is allowed. These threads are
now in a new Landlock domain, merge of their parent one (if any) with the new now in a new Landlock domain, merge of their parent one (if any) with the new
...@@ -170,12 +170,13 @@ It is recommended setting access rights to file hierarchy leaves as much as ...@@ -170,12 +170,13 @@ It is recommended setting access rights to file hierarchy leaves as much as
possible. For instance, it is better to be able to have ``~/doc/`` as a possible. For instance, it is better to be able to have ``~/doc/`` as a
read-only hierarchy and ``~/tmp/`` as a read-write hierarchy, compared to read-only hierarchy and ``~/tmp/`` as a read-write hierarchy, compared to
``~/`` as a read-only hierarchy and ``~/tmp/`` as a read-write hierarchy. ``~/`` as a read-only hierarchy and ``~/tmp/`` as a read-write hierarchy.
Following this good practice leads to self-sufficient hierarchies that don't Following this good practice leads to self-sufficient hierarchies that do not
depend on their location (i.e. parent directories). This is particularly depend on their location (i.e. parent directories). This is particularly
relevant when we want to allow linking or renaming. Indeed, having consistent relevant when we want to allow linking or renaming. Indeed, having consistent
access rights per directory enables to change the location of such directory access rights per directory enables to change the location of such directory
without relying on the destination directory access rights (except those that without relying on the destination directory access rights (except those that
are required for this operation, see `LANDLOCK_ACCESS_FS_REFER` documentation). are required for this operation, see ``LANDLOCK_ACCESS_FS_REFER``
documentation).
Having self-sufficient hierarchies also helps to tighten the required access Having self-sufficient hierarchies also helps to tighten the required access
rights to the minimal set of data. This also helps avoid sinkhole directories, rights to the minimal set of data. This also helps avoid sinkhole directories,
i.e. directories where data can be linked to but not linked from. However, i.e. directories where data can be linked to but not linked from. However,
...@@ -259,7 +260,7 @@ Backward and forward compatibility ...@@ -259,7 +260,7 @@ Backward and forward compatibility
Landlock is designed to be compatible with past and future versions of the Landlock is designed to be compatible with past and future versions of the
kernel. This is achieved thanks to the system call attributes and the kernel. This is achieved thanks to the system call attributes and the
associated bitflags, particularly the ruleset's `handled_access_fs`. Making associated bitflags, particularly the ruleset's ``handled_access_fs``. Making
handled access right explicit enables the kernel and user space to have a clear handled access right explicit enables the kernel and user space to have a clear
contract with each other. This is required to make sure sandboxing will not contract with each other. This is required to make sure sandboxing will not
get stricter with a system update, which could break applications. get stricter with a system update, which could break applications.
...@@ -380,8 +381,8 @@ by the Documentation/admin-guide/cgroup-v1/memory.rst. ...@@ -380,8 +381,8 @@ by the Documentation/admin-guide/cgroup-v1/memory.rst.
Previous limitations Previous limitations
==================== ====================
File renaming and linking (ABI 1) File renaming and linking (ABI < 2)
--------------------------------- -----------------------------------
Because Landlock targets unprivileged access controls, it needs to properly Because Landlock targets unprivileged access controls, it needs to properly
handle composition of rules. Such property also implies rules nesting. handle composition of rules. Such property also implies rules nesting.
...@@ -394,7 +395,7 @@ according to the potentially lost constraints. To protect against privilege ...@@ -394,7 +395,7 @@ according to the potentially lost constraints. To protect against privilege
escalations through renaming or linking, and for the sake of simplicity, escalations through renaming or linking, and for the sake of simplicity,
Landlock previously limited linking and renaming to the same directory. Landlock previously limited linking and renaming to the same directory.
Starting with the Landlock ABI version 2, it is now possible to securely Starting with the Landlock ABI version 2, it is now possible to securely
control renaming and linking thanks to the new `LANDLOCK_ACCESS_FS_REFER` control renaming and linking thanks to the new ``LANDLOCK_ACCESS_FS_REFER``
access right. access right.
.. _kernel_support: .. _kernel_support:
...@@ -403,14 +404,14 @@ Kernel support ...@@ -403,14 +404,14 @@ Kernel support
============== ==============
Landlock was first introduced in Linux 5.13 but it must be configured at build Landlock was first introduced in Linux 5.13 but it must be configured at build
time with `CONFIG_SECURITY_LANDLOCK=y`. Landlock must also be enabled at boot time with ``CONFIG_SECURITY_LANDLOCK=y``. Landlock must also be enabled at boot
time as the other security modules. The list of security modules enabled by time as the other security modules. The list of security modules enabled by
default is set with `CONFIG_LSM`. The kernel configuration should then default is set with ``CONFIG_LSM``. The kernel configuration should then
contains `CONFIG_LSM=landlock,[...]` with `[...]` as the list of other contains ``CONFIG_LSM=landlock,[...]`` with ``[...]`` as the list of other
potentially useful security modules for the running system (see the potentially useful security modules for the running system (see the
`CONFIG_LSM` help). ``CONFIG_LSM`` help).
If the running kernel doesn't have `landlock` in `CONFIG_LSM`, then we can If the running kernel does not have ``landlock`` in ``CONFIG_LSM``, then we can
still enable it by adding ``lsm=landlock,[...]`` to still enable it by adding ``lsm=landlock,[...]`` to
Documentation/admin-guide/kernel-parameters.rst thanks to the bootloader Documentation/admin-guide/kernel-parameters.rst thanks to the bootloader
configuration. configuration.
......
...@@ -26,7 +26,7 @@ struct landlock_ruleset_attr { ...@@ -26,7 +26,7 @@ struct landlock_ruleset_attr {
* Landlock filesystem access rights that are not part of * Landlock filesystem access rights that are not part of
* handled_access_fs are allowed. This is needed for backward * handled_access_fs are allowed. This is needed for backward
* compatibility reasons. One exception is the * compatibility reasons. One exception is the
* LANDLOCK_ACCESS_FS_REFER access right, which is always implicitly * %LANDLOCK_ACCESS_FS_REFER access right, which is always implicitly
* handled, but must still be explicitly handled to add new rules with * handled, but must still be explicitly handled to add new rules with
* this access right. * this access right.
*/ */
...@@ -128,11 +128,11 @@ struct landlock_path_beneath_attr { ...@@ -128,11 +128,11 @@ struct landlock_path_beneath_attr {
* hierarchy must also always have the same or a superset of restrictions of * hierarchy must also always have the same or a superset of restrictions of
* the source hierarchy. If it is not the case, or if the domain doesn't * the source hierarchy. If it is not the case, or if the domain doesn't
* handle this access right, such actions are denied by default with errno * handle this access right, such actions are denied by default with errno
* set to EXDEV. Linking also requires a LANDLOCK_ACCESS_FS_MAKE_* access * set to ``EXDEV``. Linking also requires a ``LANDLOCK_ACCESS_FS_MAKE_*``
* right on the destination directory, and renaming also requires a * access right on the destination directory, and renaming also requires a
* LANDLOCK_ACCESS_FS_REMOVE_* access right on the source's (file or * ``LANDLOCK_ACCESS_FS_REMOVE_*`` access right on the source's (file or
* directory) parent. Otherwise, such actions are denied with errno set to * directory) parent. Otherwise, such actions are denied with errno set to
* EACCES. The EACCES errno prevails over EXDEV to let user space * ``EACCES``. The ``EACCES`` errno prevails over ``EXDEV`` to let user space
* efficiently deal with an unrecoverable error. * efficiently deal with an unrecoverable error.
* *
* .. warning:: * .. warning::
......
...@@ -162,11 +162,10 @@ static int populate_ruleset(const char *const env_var, const int ruleset_fd, ...@@ -162,11 +162,10 @@ static int populate_ruleset(const char *const env_var, const int ruleset_fd,
LANDLOCK_ACCESS_FS_MAKE_SYM | \ LANDLOCK_ACCESS_FS_MAKE_SYM | \
LANDLOCK_ACCESS_FS_REFER) LANDLOCK_ACCESS_FS_REFER)
#define ACCESS_ABI_2 ( \
LANDLOCK_ACCESS_FS_REFER)
/* clang-format on */ /* clang-format on */
#define LANDLOCK_ABI_LAST 2
int main(const int argc, char *const argv[], char *const *const envp) int main(const int argc, char *const argv[], char *const *const envp)
{ {
const char *cmd_path; const char *cmd_path;
...@@ -196,8 +195,12 @@ int main(const int argc, char *const argv[], char *const *const envp) ...@@ -196,8 +195,12 @@ int main(const int argc, char *const argv[], char *const *const envp)
"\nexample:\n" "\nexample:\n"
"%s=\"/bin:/lib:/usr:/proc:/etc:/dev/urandom\" " "%s=\"/bin:/lib:/usr:/proc:/etc:/dev/urandom\" "
"%s=\"/dev/null:/dev/full:/dev/zero:/dev/pts:/tmp\" " "%s=\"/dev/null:/dev/full:/dev/zero:/dev/pts:/tmp\" "
"%s bash -i\n", "%s bash -i\n\n",
ENV_FS_RO_NAME, ENV_FS_RW_NAME, argv[0]); ENV_FS_RO_NAME, ENV_FS_RW_NAME, argv[0]);
fprintf(stderr,
"This sandboxer can use Landlock features "
"up to ABI version %d.\n",
LANDLOCK_ABI_LAST);
return 1; return 1;
} }
...@@ -225,12 +228,30 @@ int main(const int argc, char *const argv[], char *const *const envp) ...@@ -225,12 +228,30 @@ int main(const int argc, char *const argv[], char *const *const envp)
} }
return 1; return 1;
} }
/* Best-effort security. */ /* Best-effort security. */
if (abi < 2) { switch (abi) {
ruleset_attr.handled_access_fs &= ~ACCESS_ABI_2; case 1:
access_fs_ro &= ~ACCESS_ABI_2; /* Removes LANDLOCK_ACCESS_FS_REFER for ABI < 2 */
access_fs_rw &= ~ACCESS_ABI_2; ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER;
fprintf(stderr,
"Hint: You should update the running kernel "
"to leverage Landlock features "
"provided by ABI version %d (instead of %d).\n",
LANDLOCK_ABI_LAST, abi);
__attribute__((fallthrough));
case LANDLOCK_ABI_LAST:
break;
default:
fprintf(stderr,
"Hint: You should update this sandboxer "
"to leverage Landlock features "
"provided by ABI version %d (instead of %d).\n",
abi, LANDLOCK_ABI_LAST);
} }
access_fs_ro &= ruleset_attr.handled_access_fs;
access_fs_rw &= ruleset_attr.handled_access_fs;
ruleset_fd = ruleset_fd =
landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
......
...@@ -712,7 +712,7 @@ static inline access_mask_t maybe_remove(const struct dentry *const dentry) ...@@ -712,7 +712,7 @@ static inline access_mask_t maybe_remove(const struct dentry *const dentry)
* allowed accesses in @layer_masks_dom. * allowed accesses in @layer_masks_dom.
* *
* This is similar to check_access_path_dual() but much simpler because it only * This is similar to check_access_path_dual() but much simpler because it only
* handles walking on the same mount point and only check one set of accesses. * handles walking on the same mount point and only checks one set of accesses.
* *
* Returns: * Returns:
* - true if all the domain access rights are allowed for @dir; * - true if all the domain access rights are allowed for @dir;
......
...@@ -149,10 +149,10 @@ static const struct file_operations ruleset_fops = { ...@@ -149,10 +149,10 @@ static const struct file_operations ruleset_fops = {
* *
* Possible returned errors are: * Possible returned errors are:
* *
* - EOPNOTSUPP: Landlock is supported by the kernel but disabled at boot time; * - %EOPNOTSUPP: Landlock is supported by the kernel but disabled at boot time;
* - EINVAL: unknown @flags, or unknown access, or too small @size; * - %EINVAL: unknown @flags, or unknown access, or too small @size;
* - E2BIG or EFAULT: @attr or @size inconsistencies; * - %E2BIG or %EFAULT: @attr or @size inconsistencies;
* - ENOMSG: empty &landlock_ruleset_attr.handled_access_fs. * - %ENOMSG: empty &landlock_ruleset_attr.handled_access_fs.
*/ */
SYSCALL_DEFINE3(landlock_create_ruleset, SYSCALL_DEFINE3(landlock_create_ruleset,
const struct landlock_ruleset_attr __user *const, attr, const struct landlock_ruleset_attr __user *const, attr,
...@@ -280,7 +280,7 @@ static int get_path_from_fd(const s32 fd, struct path *const path) ...@@ -280,7 +280,7 @@ static int get_path_from_fd(const s32 fd, struct path *const path)
* @ruleset_fd: File descriptor tied to the ruleset that should be extended * @ruleset_fd: File descriptor tied to the ruleset that should be extended
* with the new rule. * with the new rule.
* @rule_type: Identify the structure type pointed to by @rule_attr (only * @rule_type: Identify the structure type pointed to by @rule_attr (only
* LANDLOCK_RULE_PATH_BENEATH for now). * %LANDLOCK_RULE_PATH_BENEATH for now).
* @rule_attr: Pointer to a rule (only of type &struct * @rule_attr: Pointer to a rule (only of type &struct
* landlock_path_beneath_attr for now). * landlock_path_beneath_attr for now).
* @flags: Must be 0. * @flags: Must be 0.
...@@ -290,17 +290,17 @@ static int get_path_from_fd(const s32 fd, struct path *const path) ...@@ -290,17 +290,17 @@ static int get_path_from_fd(const s32 fd, struct path *const path)
* *
* Possible returned errors are: * Possible returned errors are:
* *
* - EOPNOTSUPP: Landlock is supported by the kernel but disabled at boot time; * - %EOPNOTSUPP: Landlock is supported by the kernel but disabled at boot time;
* - EINVAL: @flags is not 0, or inconsistent access in the rule (i.e. * - %EINVAL: @flags is not 0, or inconsistent access in the rule (i.e.
* &landlock_path_beneath_attr.allowed_access is not a subset of the * &landlock_path_beneath_attr.allowed_access is not a subset of the
* ruleset handled accesses); * ruleset handled accesses);
* - ENOMSG: Empty accesses (e.g. &landlock_path_beneath_attr.allowed_access); * - %ENOMSG: Empty accesses (e.g. &landlock_path_beneath_attr.allowed_access);
* - EBADF: @ruleset_fd is not a file descriptor for the current thread, or a * - %EBADF: @ruleset_fd is not a file descriptor for the current thread, or a
* member of @rule_attr is not a file descriptor as expected; * member of @rule_attr is not a file descriptor as expected;
* - EBADFD: @ruleset_fd is not a ruleset file descriptor, or a member of * - %EBADFD: @ruleset_fd is not a ruleset file descriptor, or a member of
* @rule_attr is not the expected file descriptor type; * @rule_attr is not the expected file descriptor type;
* - EPERM: @ruleset_fd has no write access to the underlying ruleset; * - %EPERM: @ruleset_fd has no write access to the underlying ruleset;
* - EFAULT: @rule_attr inconsistency. * - %EFAULT: @rule_attr inconsistency.
*/ */
SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd, SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd,
const enum landlock_rule_type, rule_type, const enum landlock_rule_type, rule_type,
...@@ -378,20 +378,20 @@ SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd, ...@@ -378,20 +378,20 @@ SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd,
* @flags: Must be 0. * @flags: Must be 0.
* *
* This system call enables to enforce a Landlock ruleset on the current * This system call enables to enforce a Landlock ruleset on the current
* thread. Enforcing a ruleset requires that the task has CAP_SYS_ADMIN in its * thread. Enforcing a ruleset requires that the task has %CAP_SYS_ADMIN in its
* namespace or is running with no_new_privs. This avoids scenarios where * namespace or is running with no_new_privs. This avoids scenarios where
* unprivileged tasks can affect the behavior of privileged children. * unprivileged tasks can affect the behavior of privileged children.
* *
* Possible returned errors are: * Possible returned errors are:
* *
* - EOPNOTSUPP: Landlock is supported by the kernel but disabled at boot time; * - %EOPNOTSUPP: Landlock is supported by the kernel but disabled at boot time;
* - EINVAL: @flags is not 0. * - %EINVAL: @flags is not 0.
* - EBADF: @ruleset_fd is not a file descriptor for the current thread; * - %EBADF: @ruleset_fd is not a file descriptor for the current thread;
* - EBADFD: @ruleset_fd is not a ruleset file descriptor; * - %EBADFD: @ruleset_fd is not a ruleset file descriptor;
* - EPERM: @ruleset_fd has no read access to the underlying ruleset, or the * - %EPERM: @ruleset_fd has no read access to the underlying ruleset, or the
* current thread is not running with no_new_privs, or it doesn't have * current thread is not running with no_new_privs, or it doesn't have
* CAP_SYS_ADMIN in its namespace. * %CAP_SYS_ADMIN in its namespace.
* - E2BIG: The maximum number of stacked rulesets is reached for the current * - %E2BIG: The maximum number of stacked rulesets is reached for the current
* thread. * thread.
*/ */
SYSCALL_DEFINE2(landlock_restrict_self, const int, ruleset_fd, const __u32, SYSCALL_DEFINE2(landlock_restrict_self, const int, ruleset_fd, const __u32,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment