Mickaël Salaün | 5526b45 | 2021-04-22 17:41:22 +0200 | [diff] [blame] | 1 | .. SPDX-License-Identifier: GPL-2.0 |
| 2 | .. Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net> |
| 3 | .. Copyright © 2019-2020 ANSSI |
| 4 | |
| 5 | ================================== |
| 6 | Landlock LSM: kernel documentation |
| 7 | ================================== |
| 8 | |
| 9 | :Author: Mickaël Salaün |
Mickaël Salaün | 3e52e5b | 2022-12-09 20:38:13 +0100 | [diff] [blame] | 10 | :Date: December 2022 |
Mickaël Salaün | 5526b45 | 2021-04-22 17:41:22 +0200 | [diff] [blame] | 11 | |
| 12 | Landlock's goal is to create scoped access-control (i.e. sandboxing). To |
| 13 | harden a whole system, this feature should be available to any process, |
Daniel Burgener | dad2f20 | 2024-10-15 13:26:46 -0400 | [diff] [blame] | 14 | including unprivileged ones. Because such a process may be compromised or |
Mickaël Salaün | 5526b45 | 2021-04-22 17:41:22 +0200 | [diff] [blame] | 15 | backdoored (i.e. untrusted), Landlock's features must be safe to use from the |
| 16 | kernel and other processes point of view. Landlock's interface must therefore |
| 17 | expose a minimal attack surface. |
| 18 | |
| 19 | Landlock is designed to be usable by unprivileged processes while following the |
| 20 | system security policy enforced by other access control mechanisms (e.g. DAC, |
Daniel Burgener | dad2f20 | 2024-10-15 13:26:46 -0400 | [diff] [blame] | 21 | LSM). A Landlock rule shall not interfere with other access-controls enforced |
| 22 | on the system, only add more restrictions. |
Mickaël Salaün | 5526b45 | 2021-04-22 17:41:22 +0200 | [diff] [blame] | 23 | |
| 24 | Any user can enforce Landlock rulesets on their processes. They are merged and |
Daniel Burgener | dad2f20 | 2024-10-15 13:26:46 -0400 | [diff] [blame] | 25 | evaluated against inherited rulesets in a way that ensures that only more |
Mickaël Salaün | 5526b45 | 2021-04-22 17:41:22 +0200 | [diff] [blame] | 26 | constraints can be added. |
| 27 | |
Mauro Carvalho Chehab | d312227 | 2021-06-16 08:27:39 +0200 | [diff] [blame] | 28 | User space documentation can be found here: |
| 29 | Documentation/userspace-api/landlock.rst. |
Mickaël Salaün | 5526b45 | 2021-04-22 17:41:22 +0200 | [diff] [blame] | 30 | |
| 31 | Guiding principles for safe access controls |
| 32 | =========================================== |
| 33 | |
| 34 | * A Landlock rule shall be focused on access control on kernel objects instead |
| 35 | of syscall filtering (i.e. syscall arguments), which is the purpose of |
| 36 | seccomp-bpf. |
| 37 | * To avoid multiple kinds of side-channel attacks (e.g. leak of security |
| 38 | policies, CPU-based attacks), Landlock rules shall not be able to |
| 39 | programmatically communicate with user space. |
| 40 | * Kernel access check shall not slow down access request from unsandboxed |
| 41 | processes. |
| 42 | * Computation related to Landlock operations (e.g. enforcing a ruleset) shall |
| 43 | only impact the processes requesting them. |
Mickaël Salaün | 3e52e5b | 2022-12-09 20:38:13 +0100 | [diff] [blame] | 44 | * Resources (e.g. file descriptors) directly obtained from the kernel by a |
| 45 | sandboxed process shall retain their scoped accesses (at the time of resource |
Daniel Burgener | dad2f20 | 2024-10-15 13:26:46 -0400 | [diff] [blame] | 46 | acquisition) whatever process uses them. |
Mickaël Salaün | 3e52e5b | 2022-12-09 20:38:13 +0100 | [diff] [blame] | 47 | Cf. `File descriptor access rights`_. |
Mickaël Salaün | 5526b45 | 2021-04-22 17:41:22 +0200 | [diff] [blame] | 48 | |
Mickaël Salaün | 9e0c76b | 2022-05-06 18:11:02 +0200 | [diff] [blame] | 49 | Design choices |
| 50 | ============== |
| 51 | |
Mickaël Salaün | 3e52e5b | 2022-12-09 20:38:13 +0100 | [diff] [blame] | 52 | Inode access rights |
| 53 | ------------------- |
Mickaël Salaün | 9e0c76b | 2022-05-06 18:11:02 +0200 | [diff] [blame] | 54 | |
| 55 | All access rights are tied to an inode and what can be accessed through it. |
Mickaël Salaün | 16023b0 | 2022-09-23 17:42:06 +0200 | [diff] [blame] | 56 | Reading the content of a directory does not imply to be allowed to read the |
Mickaël Salaün | 9e0c76b | 2022-05-06 18:11:02 +0200 | [diff] [blame] | 57 | content of a listed inode. Indeed, a file name is local to its parent |
| 58 | directory, and an inode can be referenced by multiple file names thanks to |
| 59 | (hard) links. Being able to unlink a file only has a direct impact on the |
| 60 | directory, not the unlinked inode. This is the reason why |
Mickaël Salaün | 2fff00c | 2022-09-23 17:42:07 +0200 | [diff] [blame] | 61 | ``LANDLOCK_ACCESS_FS_REMOVE_FILE`` or ``LANDLOCK_ACCESS_FS_REFER`` are not |
| 62 | allowed to be tied to files but only to directories. |
Mickaël Salaün | 9e0c76b | 2022-05-06 18:11:02 +0200 | [diff] [blame] | 63 | |
Mickaël Salaün | 3e52e5b | 2022-12-09 20:38:13 +0100 | [diff] [blame] | 64 | File descriptor access rights |
| 65 | ----------------------------- |
| 66 | |
| 67 | Access rights are checked and tied to file descriptors at open time. The |
| 68 | underlying principle is that equivalent sequences of operations should lead to |
| 69 | the same results, when they are executed under the same Landlock domain. |
| 70 | |
| 71 | Taking the ``LANDLOCK_ACCESS_FS_TRUNCATE`` right as an example, it may be |
| 72 | allowed to open a file for writing without being allowed to |
| 73 | :manpage:`ftruncate` the resulting file descriptor if the related file |
Daniel Burgener | dad2f20 | 2024-10-15 13:26:46 -0400 | [diff] [blame] | 74 | hierarchy doesn't grant that access right. The following sequences of |
Mickaël Salaün | 3e52e5b | 2022-12-09 20:38:13 +0100 | [diff] [blame] | 75 | operations have the same semantic and should then have the same result: |
| 76 | |
| 77 | * ``truncate(path);`` |
| 78 | * ``int fd = open(path, O_WRONLY); ftruncate(fd); close(fd);`` |
| 79 | |
| 80 | Similarly to file access modes (e.g. ``O_RDWR``), Landlock access rights |
| 81 | attached to file descriptors are retained even if they are passed between |
| 82 | processes (e.g. through a Unix domain socket). Such access rights will then be |
| 83 | enforced even if the receiving process is not sandboxed by Landlock. Indeed, |
Daniel Burgener | dad2f20 | 2024-10-15 13:26:46 -0400 | [diff] [blame] | 84 | this is required to keep access controls consistent over the whole system, and |
Mickaël Salaün | 3e52e5b | 2022-12-09 20:38:13 +0100 | [diff] [blame] | 85 | this avoids unattended bypasses through file descriptor passing (i.e. confused |
| 86 | deputy attack). |
| 87 | |
Mickaël Salaün | 5526b45 | 2021-04-22 17:41:22 +0200 | [diff] [blame] | 88 | Tests |
| 89 | ===== |
| 90 | |
| 91 | Userspace tests for backward compatibility, ptrace restrictions and filesystem |
| 92 | support can be found here: `tools/testing/selftests/landlock/`_. |
| 93 | |
| 94 | Kernel structures |
| 95 | ================= |
| 96 | |
| 97 | Object |
| 98 | ------ |
| 99 | |
| 100 | .. kernel-doc:: security/landlock/object.h |
| 101 | :identifiers: |
| 102 | |
| 103 | Filesystem |
| 104 | ---------- |
| 105 | |
| 106 | .. kernel-doc:: security/landlock/fs.h |
| 107 | :identifiers: |
| 108 | |
| 109 | Ruleset and domain |
| 110 | ------------------ |
| 111 | |
| 112 | A domain is a read-only ruleset tied to a set of subjects (i.e. tasks' |
| 113 | credentials). Each time a ruleset is enforced on a task, the current domain is |
| 114 | duplicated and the ruleset is imported as a new layer of rules in the new |
| 115 | domain. Indeed, once in a domain, each rule is tied to a layer level. To |
| 116 | grant access to an object, at least one rule of each layer must allow the |
| 117 | requested action on the object. A task can then only transit to a new domain |
| 118 | that is the intersection of the constraints from the current domain and those |
| 119 | of a ruleset provided by the task. |
| 120 | |
| 121 | The definition of a subject is implicit for a task sandboxing itself, which |
| 122 | makes the reasoning much easier and helps avoid pitfalls. |
| 123 | |
| 124 | .. kernel-doc:: security/landlock/ruleset.h |
| 125 | :identifiers: |
| 126 | |
| 127 | .. Links |
| 128 | .. _tools/testing/selftests/landlock/: |
| 129 | https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/tools/testing/selftests/landlock/ |