History

Merge tag 'landlock_v34' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security

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

Linus Torvalds committed 5 years ago

Commit 17ae69a2 parents e6f0bf0 3532b0b72 files · +6987 −77Browse files

Showing the changes to Documentation/userspace-api (2 of 72 files). Show all

Unified · Split

2 files
  1. Documentation/userspace-api/index.rst +1 −0
  2. Documentation/userspace-api/landlock.rst +311 −0
Documentation/userspace-api/index.rst+1−0
@@ -18,6 +18,7 @@ place where this information is gathered. · 17 unmodified lines
1818
1919 no_new_privs
2020 seccomp_filter
21+ landlock
2122 unshare
2223 spec_ctrl
2324 accelerators/ocxl
Documentation/userspace-api/landlock.rst+311−0
@@ -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