130 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			130 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| .. SPDX-License-Identifier: GPL-2.0
 | |
| .. Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net>
 | |
| .. Copyright © 2019-2020 ANSSI
 | |
| 
 | |
| ==================================
 | |
| Landlock LSM: kernel documentation
 | |
| ==================================
 | |
| 
 | |
| :Author: Mickaël Salaün
 | |
| :Date: December 2022
 | |
| 
 | |
| 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,
 | |
| including unprivileged ones.  Because such process may be compromised or
 | |
| backdoored (i.e. untrusted), Landlock's features must be safe to use from the
 | |
| kernel and other processes point of view.  Landlock's interface must therefore
 | |
| expose a minimal attack surface.
 | |
| 
 | |
| Landlock is designed to be usable by unprivileged processes while following the
 | |
| system security policy enforced by other access control mechanisms (e.g. DAC,
 | |
| LSM).  Indeed, a Landlock rule shall not interfere with other access-controls
 | |
| enforced on the system, only add more restrictions.
 | |
| 
 | |
| Any user can enforce Landlock rulesets on their processes.  They are merged and
 | |
| evaluated according to the inherited ones in a way that ensures that only more
 | |
| constraints can be added.
 | |
| 
 | |
| User space documentation can be found here:
 | |
| Documentation/userspace-api/landlock.rst.
 | |
| 
 | |
| Guiding principles for safe access controls
 | |
| ===========================================
 | |
| 
 | |
| * A Landlock rule shall be focused on access control on kernel objects instead
 | |
|   of syscall filtering (i.e. syscall arguments), which is the purpose of
 | |
|   seccomp-bpf.
 | |
| * To avoid multiple kinds of side-channel attacks (e.g. leak of security
 | |
|   policies, CPU-based attacks), Landlock rules shall not be able to
 | |
|   programmatically communicate with user space.
 | |
| * Kernel access check shall not slow down access request from unsandboxed
 | |
|   processes.
 | |
| * Computation related to Landlock operations (e.g. enforcing a ruleset) shall
 | |
|   only impact the processes requesting them.
 | |
| * Resources (e.g. file descriptors) directly obtained from the kernel by a
 | |
|   sandboxed process shall retain their scoped accesses (at the time of resource
 | |
|   acquisition) whatever process use them.
 | |
|   Cf. `File descriptor access rights`_.
 | |
| 
 | |
| Design choices
 | |
| ==============
 | |
| 
 | |
| Inode access rights
 | |
| -------------------
 | |
| 
 | |
| All access rights are tied to an inode and what can be accessed through it.
 | |
| 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
 | |
| 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
 | |
| directory, not the unlinked inode.  This is the reason why
 | |
| ``LANDLOCK_ACCESS_FS_REMOVE_FILE`` or ``LANDLOCK_ACCESS_FS_REFER`` are not
 | |
| allowed to be tied to files but only to directories.
 | |
| 
 | |
| File descriptor access rights
 | |
| -----------------------------
 | |
| 
 | |
| Access rights are checked and tied to file descriptors at open time.  The
 | |
| underlying principle is that equivalent sequences of operations should lead to
 | |
| the same results, when they are executed under the same Landlock domain.
 | |
| 
 | |
| Taking the ``LANDLOCK_ACCESS_FS_TRUNCATE`` right as an example, it may be
 | |
| allowed to open a file for writing without being allowed to
 | |
| :manpage:`ftruncate` the resulting file descriptor if the related file
 | |
| hierarchy doesn't grant such access right.  The following sequences of
 | |
| operations have the same semantic and should then have the same result:
 | |
| 
 | |
| * ``truncate(path);``
 | |
| * ``int fd = open(path, O_WRONLY); ftruncate(fd); close(fd);``
 | |
| 
 | |
| Similarly to file access modes (e.g. ``O_RDWR``), Landlock access rights
 | |
| attached to file descriptors are retained even if they are passed between
 | |
| processes (e.g. through a Unix domain socket).  Such access rights will then be
 | |
| enforced even if the receiving process is not sandboxed by Landlock.  Indeed,
 | |
| this is required to keep a consistent access control over the whole system, and
 | |
| this avoids unattended bypasses through file descriptor passing (i.e. confused
 | |
| deputy attack).
 | |
| 
 | |
| Tests
 | |
| =====
 | |
| 
 | |
| Userspace tests for backward compatibility, ptrace restrictions and filesystem
 | |
| support can be found here: `tools/testing/selftests/landlock/`_.
 | |
| 
 | |
| Kernel structures
 | |
| =================
 | |
| 
 | |
| Object
 | |
| ------
 | |
| 
 | |
| .. kernel-doc:: security/landlock/object.h
 | |
|     :identifiers:
 | |
| 
 | |
| Filesystem
 | |
| ----------
 | |
| 
 | |
| .. kernel-doc:: security/landlock/fs.h
 | |
|     :identifiers:
 | |
| 
 | |
| Ruleset and domain
 | |
| ------------------
 | |
| 
 | |
| A domain is a read-only ruleset tied to a set of subjects (i.e. tasks'
 | |
| credentials).  Each time a ruleset is enforced on a task, the current domain is
 | |
| duplicated and the ruleset is imported as a new layer of rules in the new
 | |
| domain.  Indeed, once in a domain, each rule is tied to a layer level.  To
 | |
| grant access to an object, at least one rule of each layer must allow the
 | |
| requested action on the object.  A task can then only transit to a new domain
 | |
| that is the intersection of the constraints from the current domain and those
 | |
| of a ruleset provided by the task.
 | |
| 
 | |
| The definition of a subject is implicit for a task sandboxing itself, which
 | |
| makes the reasoning much easier and helps avoid pitfalls.
 | |
| 
 | |
| .. kernel-doc:: security/landlock/ruleset.h
 | |
|     :identifiers:
 | |
| 
 | |
| .. Links
 | |
| .. _tools/testing/selftests/landlock/:
 | |
|    https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/tools/testing/selftests/landlock/
 |