Pull Landlock LSM from James Morris: "Add Landlock, a new LSM from Mickaël Salaün. Briefly, Landlock provides for unprivileged application sandboxing. From Mickaël's cover letter: "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 LSM [1], it makes possible to create safe security sandboxes as new security layers in addition to the existing system-wide access-controls. This kind of sandbox is expected to help mitigate the security impact of bugs or unexpected/malicious behaviors in user-space applications. Landlock empowers any process, including unprivileged ones, to securely restrict themselves. Landlock is inspired by seccomp-bpf but instead of filtering syscalls and their raw arguments, a Landlock rule can restrict the use of kernel objects like file hierarchies, according to the kernel semantic. Landlock also takes inspiration from other OS sandbox mechanisms: XNU Sandbox, FreeBSD Capsicum or OpenBSD Pledge/Unveil. In this current form, Landlock misses some access-control features. This enables to minimize this patch series and ease review. This series still addresses multiple use cases, especially with the combined use of seccomp-bpf: applications with built-in sandboxing, init systems, security sandbox tools and security-oriented APIs [2]" The cover letter and v34 posting is here: https://lore.kernel.org/linux-security-module/20210422154123.13086-1-mic@digikod.net/ See also: https://landlock.io/ This code has had extensive design discussion and review over several years" Link: https://lore.kernel.org/lkml/50db058a-7dde-441b-a7f9-f6837fe8b69f@schaufler-ca.com/ [1] Link: https://lore.kernel.org/lkml/f646e1c7-33cf-333f-070c-0a40ad0468cd@digikod.net/ [2] * tag 'landlock_v34' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: landlock: Enable user space to infer supported features landlock: Add user and kernel documentation samples/landlock: Add a sandbox manager example selftests/landlock: Add user space tests landlock: Add syscall implementations arch: Wire up Landlock syscalls fs,security: Add sb_delete hook landlock: Support filesystem access-control LSM: Infrastructure management of the superblock landlock: Add ptrace restrictions landlock: Set up the security framework and manage credentials landlock: Add ruleset and domain management landlock: Add object management
Showing the changes to Documentation/userspace-api (2 of 72 files). Show all
Unified · Split
| @@ -18,6 +18,7 @@ place where this information is gathered. · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | no_new_privs |
| 20 | 20 | seccomp_filter |
| 21 | + landlock | |
| 21 | 22 | unshare |
| 22 | 23 | spec_ctrl |
| 23 | 24 | accelerators/ocxl |
| @@ -0,0 +1,311 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | +.. Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net> | |
| 3 | +.. Copyright © 2019-2020 ANSSI | |
| 4 | +.. Copyright © 2021 Microsoft Corporation | |
| 5 | + | |
| 6 | +===================================== | |
| 7 | +Landlock: unprivileged access control | |
| 8 | +===================================== | |
| 9 | + | |
| 10 | +:Author: Mickaël Salaün | |
| 11 | +:Date: March 2021 | |
| 12 | + | |
| 13 | +The goal of Landlock is to enable to restrict ambient rights (e.g. global | |
| 14 | +filesystem access) for a set of processes. Because Landlock is a stackable | |
| 15 | +LSM, it makes possible to create safe security sandboxes as new security layers | |
| 16 | +in addition to the existing system-wide access-controls. This kind of sandbox | |
| 17 | +is expected to help mitigate the security impact of bugs or | |
| 18 | +unexpected/malicious behaviors in user space applications. Landlock empowers | |
| 19 | +any process, including unprivileged ones, to securely restrict themselves. | |
| 20 | + | |
| 21 | +Landlock rules | |
| 22 | +============== | |
| 23 | + | |
| 24 | +A Landlock rule describes an action on an object. An object is currently a | |
| 25 | +file hierarchy, and the related filesystem actions are defined with `access | |
| 26 | +rights`_. A set of rules is aggregated in a ruleset, which can then restrict | |
| 27 | +the thread enforcing it, and its future children. | |
| 28 | + | |
| 29 | +Defining and enforcing a security policy | |
| 30 | +---------------------------------------- | |
| 31 | + | |
| 32 | +We first need to create the ruleset that will contain our rules. For this | |
| 33 | +example, the ruleset will contain rules that only allow read actions, but write | |
| 34 | +actions will be denied. The ruleset then needs to handle both of these kind of | |
| 35 | +actions. | |
| 36 | + | |
| 37 | +.. code-block:: c | |
| 38 | + | |
| 39 | + int ruleset_fd; | |
| 40 | + struct landlock_ruleset_attr ruleset_attr = { | |
| 41 | + .handled_access_fs = | |
| 42 | + LANDLOCK_ACCESS_FS_EXECUTE | | |
| 43 | + LANDLOCK_ACCESS_FS_WRITE_FILE | | |
| 44 | + LANDLOCK_ACCESS_FS_READ_FILE | | |
| 45 | + LANDLOCK_ACCESS_FS_READ_DIR | | |
| 46 | + LANDLOCK_ACCESS_FS_REMOVE_DIR | | |
| 47 | + LANDLOCK_ACCESS_FS_REMOVE_FILE | | |
| 48 | + LANDLOCK_ACCESS_FS_MAKE_CHAR | | |
| 49 | + LANDLOCK_ACCESS_FS_MAKE_DIR | | |
| 50 | + LANDLOCK_ACCESS_FS_MAKE_REG | | |
| 51 | + LANDLOCK_ACCESS_FS_MAKE_SOCK | | |
| 52 | + LANDLOCK_ACCESS_FS_MAKE_FIFO | | |
| 53 | + LANDLOCK_ACCESS_FS_MAKE_BLOCK | | |
| 54 | + LANDLOCK_ACCESS_FS_MAKE_SYM, | |
| 55 | + }; | |
| 56 | + | |
| 57 | + ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); | |
| 58 | + if (ruleset_fd < 0) { | |
| 59 | + perror("Failed to create a ruleset"); | |
| 60 | + return 1; | |
| 61 | + } | |
| 62 | + | |
| 63 | +We can now add a new rule to this ruleset thanks to the returned file | |
| 64 | +descriptor referring to this ruleset. The rule will only allow reading the | |
| 65 | +file hierarchy ``/usr``. Without another rule, write actions would then be | |
| 66 | +denied by the ruleset. To add ``/usr`` to the ruleset, we open it with the | |
| 67 | +``O_PATH`` flag and fill the &struct landlock_path_beneath_attr with this file | |
| 68 | +descriptor. | |
| 69 | + | |
| 70 | +.. code-block:: c | |
| 71 | + | |
| 72 | + int err; | |
| 73 | + struct landlock_path_beneath_attr path_beneath = { | |
| 74 | + .allowed_access = | |
| 75 | + LANDLOCK_ACCESS_FS_EXECUTE | | |
| 76 | + LANDLOCK_ACCESS_FS_READ_FILE | | |
| 77 | + LANDLOCK_ACCESS_FS_READ_DIR, | |
| 78 | + }; | |
| 79 | + | |
| 80 | + path_beneath.parent_fd = open("/usr", O_PATH | O_CLOEXEC); | |
| 81 | + if (path_beneath.parent_fd < 0) { | |
| 82 | + perror("Failed to open file"); | |
| 83 | + close(ruleset_fd); | |
| 84 | + return 1; | |
| 85 | + } | |
| 86 | + err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, | |
| 87 | + &path_beneath, 0); | |
| 88 | + close(path_beneath.parent_fd); | |
| 89 | + if (err) { | |
| 90 | + perror("Failed to update ruleset"); | |
| 91 | + close(ruleset_fd); | |
| 92 | + return 1; | |
| 93 | + } | |
| 94 | + | |
| 95 | +We now have a ruleset with one rule allowing read access to ``/usr`` while | |
| 96 | +denying all other handled accesses for the filesystem. The next step is to | |
| 97 | +restrict the current thread from gaining more privileges (e.g. thanks to a SUID | |
| 98 | +binary). | |
| 99 | + | |
| 100 | +.. code-block:: c | |
| 101 | + | |
| 102 | + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { | |
| 103 | + perror("Failed to restrict privileges"); | |
| 104 | + close(ruleset_fd); | |
| 105 | + return 1; | |
| 106 | + } | |
| 107 | + | |
| 108 | +The current thread is now ready to sandbox itself with the ruleset. | |
| 109 | + | |
| 110 | +.. code-block:: c | |
| 111 | + | |
| 112 | + if (landlock_restrict_self(ruleset_fd, 0)) { | |
| 113 | + perror("Failed to enforce ruleset"); | |
| 114 | + close(ruleset_fd); | |
| 115 | + return 1; | |
| 116 | + } | |
| 117 | + close(ruleset_fd); | |
| 118 | + | |
| 119 | +If the `landlock_restrict_self` system call succeeds, the current thread is now | |
| 120 | +restricted and this policy will be enforced on all its subsequently created | |
| 121 | +children as well. Once a thread is landlocked, there is no way to remove its | |
| 122 | +security policy; only adding more restrictions is allowed. These threads are | |
| 123 | +now in a new Landlock domain, merge of their parent one (if any) with the new | |
| 124 | +ruleset. | |
| 125 | + | |
| 126 | +Full working code can be found in `samples/landlock/sandboxer.c`_. | |
| 127 | + | |
| 128 | +Layers of file path access rights | |
| 129 | +--------------------------------- | |
| 130 | + | |
| 131 | +Each time a thread enforces a ruleset on itself, it updates its Landlock domain | |
| 132 | +with a new layer of policy. Indeed, this complementary policy is stacked with | |
| 133 | +the potentially other rulesets already restricting this thread. A sandboxed | |
| 134 | +thread can then safely add more constraints to itself with a new enforced | |
| 135 | +ruleset. | |
| 136 | + | |
| 137 | +One policy layer grants access to a file path if at least one of its rules | |
| 138 | +encountered on the path grants the access. A sandboxed thread can only access | |
| 139 | +a file path if all its enforced policy layers grant the access as well as all | |
| 140 | +the other system access controls (e.g. filesystem DAC, other LSM policies, | |
| 141 | +etc.). | |
| 142 | + | |
| 143 | +Bind mounts and OverlayFS | |
| 144 | +------------------------- | |
| 145 | + | |
| 146 | +Landlock enables to restrict access to file hierarchies, which means that these | |
| 147 | +access rights can be propagated with bind mounts (cf. | |
| 148 | +:doc:`/filesystems/sharedsubtree`) but not with :doc:`/filesystems/overlayfs`. | |
| 149 | + | |
| 150 | +A bind mount mirrors a source file hierarchy to a destination. The destination | |
| 151 | +hierarchy is then composed of the exact same files, on which Landlock rules can | |
| 152 | +be tied, either via the source or the destination path. These rules restrict | |
| 153 | +access when they are encountered on a path, which means that they can restrict | |
| 154 | +access to multiple file hierarchies at the same time, whether these hierarchies | |
| 155 | +are the result of bind mounts or not. | |
| 156 | + | |
| 157 | +An OverlayFS mount point consists of upper and lower layers. These layers are | |
| 158 | +combined in a merge directory, result of the mount point. This merge hierarchy | |
| 159 | +may include files from the upper and lower layers, but modifications performed | |
| 160 | +on the merge hierarchy only reflects on the upper layer. From a Landlock | |
| 161 | +policy point of view, each OverlayFS layers and merge hierarchies are | |
| 162 | +standalone and contains their own set of files and directories, which is | |
| 163 | +different from bind mounts. A policy restricting an OverlayFS layer will not | |
| 164 | +restrict the resulted merged hierarchy, and vice versa. Landlock users should | |
| 165 | +then only think about file hierarchies they want to allow access to, regardless | |
| 166 | +of the underlying filesystem. | |
| 167 | + | |
| 168 | +Inheritance | |
| 169 | +----------- | |
| 170 | + | |
| 171 | +Every new thread resulting from a :manpage:`clone(2)` inherits Landlock domain | |
| 172 | +restrictions from its parent. This is similar to the seccomp inheritance (cf. | |
| 173 | +:doc:`/userspace-api/seccomp_filter`) or any other LSM dealing with task's | |
| 174 | +:manpage:`credentials(7)`. For instance, one process's thread may apply | |
| 175 | +Landlock rules to itself, but they will not be automatically applied to other | |
| 176 | +sibling threads (unlike POSIX thread credential changes, cf. | |
| 177 | +:manpage:`nptl(7)`). | |
| 178 | + | |
| 179 | +When a thread sandboxes itself, we have the guarantee that the related security | |
| 180 | +policy will stay enforced on all this thread's descendants. This allows | |
| 181 | +creating standalone and modular security policies per application, which will | |
| 182 | +automatically be composed between themselves according to their runtime parent | |
| 183 | +policies. | |
| 184 | + | |
| 185 | +Ptrace restrictions | |
| 186 | +------------------- | |
| 187 | + | |
| 188 | +A sandboxed process has less privileges than a non-sandboxed process and must | |
| 189 | +then be subject to additional restrictions when manipulating another process. | |
| 190 | +To be allowed to use :manpage:`ptrace(2)` and related syscalls on a target | |
| 191 | +process, a sandboxed process should have a subset of the target process rules, | |
| 192 | +which means the tracee must be in a sub-domain of the tracer. | |
| 193 | + | |
| 194 | +Kernel interface | |
| 195 | +================ | |
| 196 | + | |
| 197 | +Access rights | |
| 198 | +------------- | |
| 199 | + | |
| 200 | +.. kernel-doc:: include/uapi/linux/landlock.h | |
| 201 | + :identifiers: fs_access | |
| 202 | + | |
| 203 | +Creating a new ruleset | |
| 204 | +---------------------- | |
| 205 | + | |
| 206 | +.. kernel-doc:: security/landlock/syscalls.c | |
| 207 | + :identifiers: sys_landlock_create_ruleset | |
| 208 | + | |
| 209 | +.. kernel-doc:: include/uapi/linux/landlock.h | |
| 210 | + :identifiers: landlock_ruleset_attr | |
| 211 | + | |
| 212 | +Extending a ruleset | |
| 213 | +------------------- | |
| 214 | + | |
| 215 | +.. kernel-doc:: security/landlock/syscalls.c | |
| 216 | + :identifiers: sys_landlock_add_rule | |
| 217 | + | |
| 218 | +.. kernel-doc:: include/uapi/linux/landlock.h | |
| 219 | + :identifiers: landlock_rule_type landlock_path_beneath_attr | |
| 220 | + | |
| 221 | +Enforcing a ruleset | |
| 222 | +------------------- | |
| 223 | + | |
| 224 | +.. kernel-doc:: security/landlock/syscalls.c | |
| 225 | + :identifiers: sys_landlock_restrict_self | |
| 226 | + | |
| 227 | +Current limitations | |
| 228 | +=================== | |
| 229 | + | |
| 230 | +File renaming and linking | |
| 231 | +------------------------- | |
| 232 | + | |
| 233 | +Because Landlock targets unprivileged access controls, it is needed to properly | |
| 234 | +handle composition of rules. Such property also implies rules nesting. | |
| 235 | +Properly handling multiple layers of ruleset, each one of them able to restrict | |
| 236 | +access to files, also implies to inherit the ruleset restrictions from a parent | |
| 237 | +to its hierarchy. Because files are identified and restricted by their | |
| 238 | +hierarchy, moving or linking a file from one directory to another implies to | |
| 239 | +propagate the hierarchy constraints. To protect against privilege escalations | |
| 240 | +through renaming or linking, and for the sake of simplicity, Landlock currently | |
| 241 | +limits linking and renaming to the same directory. Future Landlock evolutions | |
| 242 | +will enable more flexibility for renaming and linking, with dedicated ruleset | |
| 243 | +flags. | |
| 244 | + | |
| 245 | +Filesystem topology modification | |
| 246 | +-------------------------------- | |
| 247 | + | |
| 248 | +As for file renaming and linking, a sandboxed thread cannot modify its | |
| 249 | +filesystem topology, whether via :manpage:`mount(2)` or | |
| 250 | +:manpage:`pivot_root(2)`. However, :manpage:`chroot(2)` calls are not denied. | |
| 251 | + | |
| 252 | +Special filesystems | |
| 253 | +------------------- | |
| 254 | + | |
| 255 | +Access to regular files and directories can be restricted by Landlock, | |
| 256 | +according to the handled accesses of a ruleset. However, files that do not | |
| 257 | +come from a user-visible filesystem (e.g. pipe, socket), but can still be | |
| 258 | +accessed through ``/proc/<pid>/fd/*``, cannot currently be explicitly | |
| 259 | +restricted. Likewise, some special kernel filesystems such as nsfs, which can | |
| 260 | +be accessed through ``/proc/<pid>/ns/*``, cannot currently be explicitly | |
| 261 | +restricted. However, thanks to the `ptrace restrictions`_, access to such | |
| 262 | +sensitive ``/proc`` files are automatically restricted according to domain | |
| 263 | +hierarchies. Future Landlock evolutions could still enable to explicitly | |
| 264 | +restrict such paths with dedicated ruleset flags. | |
| 265 | + | |
| 266 | +Ruleset layers | |
| 267 | +-------------- | |
| 268 | + | |
| 269 | +There is a limit of 64 layers of stacked rulesets. This can be an issue for a | |
| 270 | +task willing to enforce a new ruleset in complement to its 64 inherited | |
| 271 | +rulesets. Once this limit is reached, sys_landlock_restrict_self() returns | |
| 272 | +E2BIG. It is then strongly suggested to carefully build rulesets once in the | |
| 273 | +life of a thread, especially for applications able to launch other applications | |
| 274 | +that may also want to sandbox themselves (e.g. shells, container managers, | |
| 275 | +etc.). | |
| 276 | + | |
| 277 | +Memory usage | |
| 278 | +------------ | |
| 279 | + | |
| 280 | +Kernel memory allocated to create rulesets is accounted and can be restricted | |
| 281 | +by the :doc:`/admin-guide/cgroup-v1/memory`. | |
| 282 | + | |
| 283 | +Questions and answers | |
| 284 | +===================== | |
| 285 | + | |
| 286 | +What about user space sandbox managers? | |
| 287 | +--------------------------------------- | |
| 288 | + | |
| 289 | +Using user space process to enforce restrictions on kernel resources can lead | |
| 290 | +to race conditions or inconsistent evaluations (i.e. `Incorrect mirroring of | |
| 291 | +the OS code and state | |
| 292 | +<https://www.ndss-symposium.org/ndss2003/traps-and-pitfalls-practical-problems-system-call-interposition-based-security-tools/>`_). | |
| 293 | + | |
| 294 | +What about namespaces and containers? | |
| 295 | +------------------------------------- | |
| 296 | + | |
| 297 | +Namespaces can help create sandboxes but they are not designed for | |
| 298 | +access-control and then miss useful features for such use case (e.g. no | |
| 299 | +fine-grained restrictions). Moreover, their complexity can lead to security | |
| 300 | +issues, especially when untrusted processes can manipulate them (cf. | |
| 301 | +`Controlling access to user namespaces <https://lwn.net/Articles/673597/>`_). | |
| 302 | + | |
| 303 | +Additional documentation | |
| 304 | +======================== | |
| 305 | + | |
| 306 | +* :doc:`/security/landlock` | |
| 307 | +* https://landlock.io | |
| 308 | + | |
| 309 | +.. Links | |
| 310 | +.. _samples/landlock/sandboxer.c: | |
| 311 | + https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/samples/landlock/sandboxer.c | |