← Documents Documentation/userspace-api/landlock.rst GitHub 원문 ↗

Linux 6.18.37 · Userspace API

Landlock: 권한 없는 접근 제어

권한 없는 프로세스가 파일시스템·TCP·IPC 권한을 스스로 제한하는 Landlock ruleset, ABI 호환성, 제한 사항과 kernel 설정을 설명합니다.

Source pathDocumentation/userspace-api/landlock.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

landlock.rst:1-710

Landlock은 기존 DAC·LSM 위에 프로세스가 스스로 단조롭게 더 강한 제한을 쌓는 권한 없는 sandbox API입니다. ruleset에서 처리할 권한을 기본 거부로 선언하고 파일 계층·TCP port 허용 규칙을 추가한 뒤 `PR_SET_NO_NEW_PRIVS`와 `landlock_restrict_self()`로 현재 thread와 자식에게 강제합니다.

실무에서는 runtime ABI 조회와 best-effort 기능 선택, leaf 중심 파일 계층 설계, WRITE_FILE·TRUNCATE의 동시 취급, open 시점에 descriptor에 결합되는 TRUNCATE·IOCTL_DEV 권한, bind mount와 OverlayFS의 서로 다른 객체 의미를 함께 고려해야 합니다.

문서는 ABI 1~7의 기능 변화, 최대 16개 ruleset layer, 특수 filesystem·IOCTL의 현재 제한, `CONFIG_SECURITY_LANDLOCK`, `CONFIG_LSM`, boot `lsm=` 설정과 audit 문서까지 포함합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
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-2022 Microsoft Corporation
5
6 =====================================
7 Landlock: unprivileged access control
8 =====================================
9
10 :Author: Mickaël Salaün
11 :Date: March 2025
12
13 The goal of Landlock is to enable restriction of ambient rights (e.g. global
14 filesystem or network access) for a set of processes. Because Landlock
15 is a stackable LSM, it makes it possible to create safe security sandboxes as
16 new security layers in addition to the existing system-wide access-controls.
17 This kind of sandbox 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 We can quickly make sure that Landlock is enabled in the running system by
22 looking for "landlock: Up and running" in kernel logs (as root):
23 ``dmesg | grep landlock || journalctl -kb -g landlock`` .
24 Developers can also easily check for Landlock support with a
25 :ref:`related system call <landlock_abi_versions>`.
26 If Landlock is not currently supported, we need to
27 :ref:`configure the kernel appropriately <kernel_support>`.
28
29 Landlock rules
30 ==============
31
32 A Landlock rule describes an action on an object which the process intends to
33 perform. A set of rules is aggregated in a ruleset, which can then restrict
34 the thread enforcing it, and its future children.
35
36 The two existing types of rules are:
37
38 Filesystem rules
39 For these rules, the object is a file hierarchy,
40 and the related filesystem actions are defined with
41 `filesystem access rights`.
42
43 Network rules (since ABI v4)
44 For these rules, the object is a TCP port,
45 and the related actions are defined with `network access rights`.
46
47 Defining and enforcing a security policy
48 ----------------------------------------
49
50 We first need to define the ruleset that will contain our rules.
51
52 For this example, the ruleset will contain rules that only allow filesystem
53 read actions and establish a specific TCP connection. Filesystem write
54 actions and other TCP actions will be denied.
55
56 The ruleset then needs to handle both these kinds of actions. This is
57 required for backward and forward compatibility (i.e. the kernel and user
58 space may not know each other's supported restrictions), hence the need
59 to be explicit about the denied-by-default access rights.
60
61 .. code-block:: c
62
63 struct landlock_ruleset_attr ruleset_attr = {
64 .handled_access_fs =
65 LANDLOCK_ACCESS_FS_EXECUTE |
66 LANDLOCK_ACCESS_FS_WRITE_FILE |
67 LANDLOCK_ACCESS_FS_READ_FILE |
68 LANDLOCK_ACCESS_FS_READ_DIR |
69 LANDLOCK_ACCESS_FS_REMOVE_DIR |
70 LANDLOCK_ACCESS_FS_REMOVE_FILE |
71 LANDLOCK_ACCESS_FS_MAKE_CHAR |
72 LANDLOCK_ACCESS_FS_MAKE_DIR |
73 LANDLOCK_ACCESS_FS_MAKE_REG |
74 LANDLOCK_ACCESS_FS_MAKE_SOCK |
75 LANDLOCK_ACCESS_FS_MAKE_FIFO |
76 LANDLOCK_ACCESS_FS_MAKE_BLOCK |
77 LANDLOCK_ACCESS_FS_MAKE_SYM |
78 LANDLOCK_ACCESS_FS_REFER |
79 LANDLOCK_ACCESS_FS_TRUNCATE |
80 LANDLOCK_ACCESS_FS_IOCTL_DEV,
81 .handled_access_net =
82 LANDLOCK_ACCESS_NET_BIND_TCP |
83 LANDLOCK_ACCESS_NET_CONNECT_TCP,
84 .scoped =
85 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
86 LANDLOCK_SCOPE_SIGNAL,
87 };
88
89 Because we may not know which kernel version an application will be executed
90 on, it is safer to follow a best-effort security approach. Indeed, we
91 should try to protect users as much as possible whatever the kernel they are
92 using.
93
94 To be compatible with older Linux versions, we detect the available Landlock ABI
95 version, and only use the available subset of access rights:
96
97 .. code-block:: c
98
99 int abi;
100
101 abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
102 if (abi < 0) {
103 /* Degrades gracefully if Landlock is not handled. */
104 perror("The running kernel does not enable to use Landlock");
105 return 0;
106 }
107 switch (abi) {
108 case 1:
109 /* Removes LANDLOCK_ACCESS_FS_REFER for ABI < 2 */
110 ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER;
111 __attribute__((fallthrough));
112 case 2:
113 /* Removes LANDLOCK_ACCESS_FS_TRUNCATE for ABI < 3 */
114 ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
115 __attribute__((fallthrough));
116 case 3:
117 /* Removes network support for ABI < 4 */
118 ruleset_attr.handled_access_net &=
119 ~(LANDLOCK_ACCESS_NET_BIND_TCP |
120 LANDLOCK_ACCESS_NET_CONNECT_TCP);
121 __attribute__((fallthrough));
122 case 4:
123 /* Removes LANDLOCK_ACCESS_FS_IOCTL_DEV for ABI < 5 */
124 ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_IOCTL_DEV;
125 __attribute__((fallthrough));
126 case 5:
127 /* Removes LANDLOCK_SCOPE_* for ABI < 6 */
128 ruleset_attr.scoped &= ~(LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
129 LANDLOCK_SCOPE_SIGNAL);
130 }
131
132 This enables the creation of an inclusive ruleset that will contain our rules.
133
134 .. code-block:: c
135
136 int ruleset_fd;
137
138 ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
139 if (ruleset_fd < 0) {
140 perror("Failed to create a ruleset");
141 return 1;
142 }
143
144 We can now add a new rule to this ruleset thanks to the returned file
145 descriptor referring to this ruleset. The rule will only allow reading the
146 file hierarchy ``/usr``. Without another rule, write actions would then be
147 denied by the ruleset. To add ``/usr`` to the ruleset, we open it with the
148 ``O_PATH`` flag and fill the &struct landlock_path_beneath_attr with this file
149 descriptor.
150
151 .. code-block:: c
152
153 int err;
154 struct landlock_path_beneath_attr path_beneath = {
155 .allowed_access =
156 LANDLOCK_ACCESS_FS_EXECUTE |
157 LANDLOCK_ACCESS_FS_READ_FILE |
158 LANDLOCK_ACCESS_FS_READ_DIR,
159 };
160
161 path_beneath.parent_fd = open("/usr", O_PATH | O_CLOEXEC);
162 if (path_beneath.parent_fd < 0) {
163 perror("Failed to open file");
164 close(ruleset_fd);
165 return 1;
166 }
167 err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
168 &path_beneath, 0);
169 close(path_beneath.parent_fd);
170 if (err) {
171 perror("Failed to update ruleset");
172 close(ruleset_fd);
173 return 1;
174 }
175
176 It may also be required to create rules following the same logic as explained
177 for the ruleset creation, by filtering access rights according to the Landlock
178 ABI version. In this example, this is not required because all of the requested
179 ``allowed_access`` rights are already available in ABI 1.
180
181 For network access-control, we can add a set of rules that allow to use a port
182 number for a specific action: HTTPS connections.
183
184 .. code-block:: c
185
186 struct landlock_net_port_attr net_port = {
187 .allowed_access = LANDLOCK_ACCESS_NET_CONNECT_TCP,
188 .port = 443,
189 };
190
191 err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
192 &net_port, 0);
193
194 The next step is to restrict the current thread from gaining more privileges
195 (e.g. through a SUID binary). We now have a ruleset with the first rule
196 allowing read access to ``/usr`` while denying all other handled accesses for
197 the filesystem, and a second rule allowing HTTPS connections.
198
199 .. code-block:: c
200
201 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
202 perror("Failed to restrict privileges");
203 close(ruleset_fd);
204 return 1;
205 }
206
207 The current thread is now ready to sandbox itself with the ruleset.
208
209 .. code-block:: c
210
211 if (landlock_restrict_self(ruleset_fd, 0)) {
212 perror("Failed to enforce ruleset");
213 close(ruleset_fd);
214 return 1;
215 }
216 close(ruleset_fd);
217
218 If the ``landlock_restrict_self`` system call succeeds, the current thread is
219 now restricted and this policy will be enforced on all its subsequently created
220 children as well. Once a thread is landlocked, there is no way to remove its
221 security policy; only adding more restrictions is allowed. These threads are
222 now in a new Landlock domain, which is a merger of their parent one (if any)
223 with the new ruleset.
224
225 Full working code can be found in `samples/landlock/sandboxer.c`_.
226
227 Good practices
228 --------------
229
230 It is recommended to set access rights to file hierarchy leaves as much as
231 possible. For instance, it is better to be able to have ``~/doc/`` as a
232 read-only hierarchy and ``~/tmp/`` as a read-write hierarchy, compared to
233 ``~/`` as a read-only hierarchy and ``~/tmp/`` as a read-write hierarchy.
234 Following this good practice leads to self-sufficient hierarchies that do not
235 depend on their location (i.e. parent directories). This is particularly
236 relevant when we want to allow linking or renaming. Indeed, having consistent
237 access rights per directory enables changing the location of such directories
238 without relying on the destination directory access rights (except those that
239 are required for this operation, see ``LANDLOCK_ACCESS_FS_REFER``
240 documentation).
241
242 Having self-sufficient hierarchies also helps to tighten the required access
243 rights to the minimal set of data. This also helps avoid sinkhole directories,
244 i.e. directories where data can be linked to but not linked from. However,
245 this depends on data organization, which might not be controlled by developers.
246 In this case, granting read-write access to ``~/tmp/``, instead of write-only
247 access, would potentially allow moving ``~/tmp/`` to a non-readable directory
248 and still keep the ability to list the content of ``~/tmp/``.
249
250 Layers of file path access rights
251 ---------------------------------
252
253 Each time a thread enforces a ruleset on itself, it updates its Landlock domain
254 with a new layer of policy. This complementary policy is stacked with any
255 other rulesets potentially already restricting this thread. A sandboxed thread
256 can then safely add more constraints to itself with a new enforced ruleset.
257
258 One policy layer grants access to a file path if at least one of its rules
259 encountered on the path grants the access. A sandboxed thread can only access
260 a file path if all its enforced policy layers grant the access as well as all
261 the other system access controls (e.g. filesystem DAC, other LSM policies,
262 etc.).
263
264 Bind mounts and OverlayFS
265 -------------------------
266
267 Landlock enables restricting access to file hierarchies, which means that these
268 access rights can be propagated with bind mounts (cf.
269 Documentation/filesystems/sharedsubtree.rst) but not with
270 Documentation/filesystems/overlayfs.rst.
271
272 A bind mount mirrors a source file hierarchy to a destination. The destination
273 hierarchy is then composed of the exact same files, on which Landlock rules can
274 be tied, either via the source or the destination path. These rules restrict
275 access when they are encountered on a path, which means that they can restrict
276 access to multiple file hierarchies at the same time, whether these hierarchies
277 are the result of bind mounts or not.
278
279 An OverlayFS mount point consists of upper and lower layers. These layers are
280 combined in a merge directory, and that merged directory becomes available at
281 the mount point. This merge hierarchy may include files from the upper and
282 lower layers, but modifications performed on the merge hierarchy only reflect
283 on the upper layer. From a Landlock policy point of view, all OverlayFS layers
284 and merge hierarchies are standalone and each contains their own set of files
285 and directories, which is different from bind mounts. A policy restricting an
286 OverlayFS layer will not restrict the resulted merged hierarchy, and vice versa.
287 Landlock users should then only think about file hierarchies they want to allow
288 access to, regardless of the underlying filesystem.
289
290 Inheritance
291 -----------
292
293 Every new thread resulting from a :manpage:`clone(2)` inherits Landlock domain
294 restrictions from its parent. This is similar to seccomp inheritance (cf.
295 Documentation/userspace-api/seccomp_filter.rst) or any other LSM dealing with
296 task's :manpage:`credentials(7)`. For instance, one process's thread may apply
297 Landlock rules to itself, but they will not be automatically applied to other
298 sibling threads (unlike POSIX thread credential changes, cf.
299 :manpage:`nptl(7)`).
300
301 When a thread sandboxes itself, we have the guarantee that the related security
302 policy will stay enforced on all this thread's descendants. This allows
303 creating standalone and modular security policies per application, which will
304 automatically be composed between themselves according to their runtime parent
305 policies.
306
307 Ptrace restrictions
308 -------------------
309
310 A sandboxed process has less privileges than a non-sandboxed process and must
311 then be subject to additional restrictions when manipulating another process.
312 To be allowed to use :manpage:`ptrace(2)` and related syscalls on a target
313 process, a sandboxed process should have a superset of the target process's
314 access rights, which means the tracee must be in a sub-domain of the tracer.
315
316 IPC scoping
317 -----------
318
319 Similar to the implicit `Ptrace restrictions`_, we may want to further restrict
320 interactions between sandboxes. Therefore, at ruleset creation time, each
321 Landlock domain can restrict the scope for certain operations, so that these
322 operations can only reach out to processes within the same Landlock domain or in
323 a nested Landlock domain (the "scope").
324
325 The operations which can be scoped are:
326
327 ``LANDLOCK_SCOPE_SIGNAL``
328 This limits the sending of signals to target processes which run within the
329 same or a nested Landlock domain.
330
331 ``LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET``
332 This limits the set of abstract :manpage:`unix(7)` sockets to which we can
333 :manpage:`connect(2)` to socket addresses which were created by a process in
334 the same or a nested Landlock domain.
335
336 A :manpage:`sendto(2)` on a non-connected datagram socket is treated as if
337 it were doing an implicit :manpage:`connect(2)` and will be blocked if the
338 remote end does not stem from the same or a nested Landlock domain.
339
340 A :manpage:`sendto(2)` on a socket which was previously connected will not
341 be restricted. This works for both datagram and stream sockets.
342
343 IPC scoping does not support exceptions via :manpage:`landlock_add_rule(2)`.
344 If an operation is scoped within a domain, no rules can be added to allow access
345 to resources or processes outside of the scope.
346
347 Truncating files
348 ----------------
349
350 The operations covered by ``LANDLOCK_ACCESS_FS_WRITE_FILE`` and
351 ``LANDLOCK_ACCESS_FS_TRUNCATE`` both change the contents of a file and sometimes
352 overlap in non-intuitive ways. It is recommended to always specify both of
353 these together.
354
355 A particularly surprising example is :manpage:`creat(2)`. The name suggests
356 that this system call requires the rights to create and write files. However,
357 it also requires the truncate right if an existing file under the same name is
358 already present.
359
360 It should also be noted that truncating files does not require the
361 ``LANDLOCK_ACCESS_FS_WRITE_FILE`` right. Apart from the :manpage:`truncate(2)`
362 system call, this can also be done through :manpage:`open(2)` with the flags
363 ``O_RDONLY | O_TRUNC``.
364
365 The truncate right is associated with the opened file (see below).
366
367 Rights associated with file descriptors
368 ---------------------------------------
369
370 When opening a file, the availability of the ``LANDLOCK_ACCESS_FS_TRUNCATE`` and
371 ``LANDLOCK_ACCESS_FS_IOCTL_DEV`` rights is associated with the newly created
372 file descriptor and will be used for subsequent truncation and ioctl attempts
373 using :manpage:`ftruncate(2)` and :manpage:`ioctl(2)`. The behavior is similar
374 to opening a file for reading or writing, where permissions are checked during
375 :manpage:`open(2)`, but not during the subsequent :manpage:`read(2)` and
376 :manpage:`write(2)` calls.
377
378 As a consequence, it is possible that a process has multiple open file
379 descriptors referring to the same file, but Landlock enforces different things
380 when operating with these file descriptors. This can happen when a Landlock
381 ruleset gets enforced and the process keeps file descriptors which were opened
382 both before and after the enforcement. It is also possible to pass such file
383 descriptors between processes, keeping their Landlock properties, even when some
384 of the involved processes do not have an enforced Landlock ruleset.
385
386 Compatibility
387 =============
388
389 Backward and forward compatibility
390 ----------------------------------
391
392 Landlock is designed to be compatible with past and future versions of the
393 kernel. This is achieved thanks to the system call attributes and the
394 associated bitflags, particularly the ruleset's ``handled_access_fs``. Making
395 handled access rights explicit enables the kernel and user space to have a clear
396 contract with each other. This is required to make sure sandboxing will not
397 get stricter with a system update, which could break applications.
398
399 Developers can subscribe to the `Landlock mailing list
400 <https://subspace.kernel.org/lists.linux.dev.html>`_ to knowingly update and
401 test their applications with the latest available features. In the interest of
402 users, and because they may use different kernel versions, it is strongly
403 encouraged to follow a best-effort security approach by checking the Landlock
404 ABI version at runtime and only enforcing the supported features.
405
406 .. _landlock_abi_versions:
407
408 Landlock ABI versions
409 ---------------------
410
411 The Landlock ABI version can be read with the sys_landlock_create_ruleset()
412 system call:
413
414 .. code-block:: c
415
416 int abi;
417
418 abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
419 if (abi < 0) {
420 switch (errno) {
421 case ENOSYS:
422 printf("Landlock is not supported by the current kernel.\n");
423 break;
424 case EOPNOTSUPP:
425 printf("Landlock is currently disabled.\n");
426 break;
427 }
428 return 0;
429 }
430 if (abi >= 2) {
431 printf("Landlock supports LANDLOCK_ACCESS_FS_REFER.\n");
432 }
433
434 The following kernel interfaces are implicitly supported by the first ABI
435 version. Features only supported from a specific version are explicitly marked
436 as such.
437
438 Kernel interface
439 ================
440
441 Access rights
442 -------------
443
444 .. kernel-doc:: include/uapi/linux/landlock.h
445 :identifiers: fs_access net_access scope
446
447 Creating a new ruleset
448 ----------------------
449
450 .. kernel-doc:: security/landlock/syscalls.c
451 :identifiers: sys_landlock_create_ruleset
452
453 .. kernel-doc:: include/uapi/linux/landlock.h
454 :identifiers: landlock_ruleset_attr
455
456 Extending a ruleset
457 -------------------
458
459 .. kernel-doc:: security/landlock/syscalls.c
460 :identifiers: sys_landlock_add_rule
461
462 .. kernel-doc:: include/uapi/linux/landlock.h
463 :identifiers: landlock_rule_type landlock_path_beneath_attr
464 landlock_net_port_attr
465
466 Enforcing a ruleset
467 -------------------
468
469 .. kernel-doc:: security/landlock/syscalls.c
470 :identifiers: sys_landlock_restrict_self
471
472 Current limitations
473 ===================
474
475 Filesystem topology modification
476 --------------------------------
477
478 Threads sandboxed with filesystem restrictions cannot modify filesystem
479 topology, whether via :manpage:`mount(2)` or :manpage:`pivot_root(2)`.
480 However, :manpage:`chroot(2)` calls are not denied.
481
482 Special filesystems
483 -------------------
484
485 Access to regular files and directories can be restricted by Landlock,
486 according to the handled accesses of a ruleset. However, files that do not
487 come from a user-visible filesystem (e.g. pipe, socket), but can still be
488 accessed through ``/proc/<pid>/fd/*``, cannot currently be explicitly
489 restricted. Likewise, some special kernel filesystems such as nsfs, which can
490 be accessed through ``/proc/<pid>/ns/*``, cannot currently be explicitly
491 restricted. However, thanks to the `ptrace restrictions`_, access to such
492 sensitive ``/proc`` files are automatically restricted according to domain
493 hierarchies. Future Landlock evolutions could still enable to explicitly
494 restrict such paths with dedicated ruleset flags.
495
496 Ruleset layers
497 --------------
498
499 There is a limit of 16 layers of stacked rulesets. This can be an issue for a
500 task willing to enforce a new ruleset in complement to its 16 inherited
501 rulesets. Once this limit is reached, sys_landlock_restrict_self() returns
502 E2BIG. It is then strongly suggested to carefully build rulesets once in the
503 life of a thread, especially for applications able to launch other applications
504 that may also want to sandbox themselves (e.g. shells, container managers,
505 etc.).
506
507 Memory usage
508 ------------
509
510 Kernel memory allocated to create rulesets is accounted and can be restricted
511 by the Documentation/admin-guide/cgroup-v1/memory.rst.
512
513 IOCTL support
514 -------------
515
516 The ``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right restricts the use of
517 :manpage:`ioctl(2)`, but it only applies to *newly opened* device files. This
518 means specifically that pre-existing file descriptors like stdin, stdout and
519 stderr are unaffected.
520
521 Users should be aware that TTY devices have traditionally permitted to control
522 other processes on the same TTY through the ``TIOCSTI`` and ``TIOCLINUX`` IOCTL
523 commands. Both of these require ``CAP_SYS_ADMIN`` on modern Linux systems, but
524 the behavior is configurable for ``TIOCSTI``.
525
526 On older systems, it is therefore recommended to close inherited TTY file
527 descriptors, or to reopen them from ``/proc/self/fd/*`` without the
528 ``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right, if possible.
529
530 Landlock's IOCTL support is coarse-grained at the moment, but may become more
531 fine-grained in the future. Until then, users are advised to establish the
532 guarantees that they need through the file hierarchy, by only allowing the
533 ``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right on files where it is really required.
534
535 Previous limitations
536 ====================
537
538 File renaming and linking (ABI < 2)
539 -----------------------------------
540
541 Because Landlock targets unprivileged access controls, it needs to properly
542 handle composition of rules. Such property also implies rules nesting.
543 Properly handling multiple layers of rulesets, each one of them able to
544 restrict access to files, also implies inheritance of the ruleset restrictions
545 from a parent to its hierarchy. Because files are identified and restricted by
546 their hierarchy, moving or linking a file from one directory to another implies
547 propagation of the hierarchy constraints, or restriction of these actions
548 according to the potentially lost constraints. To protect against privilege
549 escalations through renaming or linking, and for the sake of simplicity,
550 Landlock previously limited linking and renaming to the same directory.
551 Starting with the Landlock ABI version 2, it is now possible to securely
552 control renaming and linking thanks to the new ``LANDLOCK_ACCESS_FS_REFER``
553 access right.
554
555 File truncation (ABI < 3)
556 -------------------------
557
558 File truncation could not be denied before the third Landlock ABI, so it is
559 always allowed when using a kernel that only supports the first or second ABI.
560
561 Starting with the Landlock ABI version 3, it is now possible to securely control
562 truncation thanks to the new ``LANDLOCK_ACCESS_FS_TRUNCATE`` access right.
563
564 TCP bind and connect (ABI < 4)
565 ------------------------------
566
567 Starting with the Landlock ABI version 4, it is now possible to restrict TCP
568 bind and connect actions to only a set of allowed ports thanks to the new
569 ``LANDLOCK_ACCESS_NET_BIND_TCP`` and ``LANDLOCK_ACCESS_NET_CONNECT_TCP``
570 access rights.
571
572 Device IOCTL (ABI < 5)
573 ----------------------
574
575 IOCTL operations could not be denied before the fifth Landlock ABI, so
576 :manpage:`ioctl(2)` is always allowed when using a kernel that only supports an
577 earlier ABI.
578
579 Starting with the Landlock ABI version 5, it is possible to restrict the use of
580 :manpage:`ioctl(2)` on character and block devices using the new
581 ``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right.
582
583 Abstract UNIX socket (ABI < 6)
584 ------------------------------
585
586 Starting with the Landlock ABI version 6, it is possible to restrict
587 connections to an abstract :manpage:`unix(7)` socket by setting
588 ``LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET`` to the ``scoped`` ruleset attribute.
589
590 Signal (ABI < 6)
591 ----------------
592
593 Starting with the Landlock ABI version 6, it is possible to restrict
594 :manpage:`signal(7)` sending by setting ``LANDLOCK_SCOPE_SIGNAL`` to the
595 ``scoped`` ruleset attribute.
596
597 Logging (ABI < 7)
598 -----------------
599
600 Starting with the Landlock ABI version 7, it is possible to control logging of
601 Landlock audit events with the ``LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF``,
602 ``LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON``, and
603 ``LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF`` flags passed to
604 sys_landlock_restrict_self(). See Documentation/admin-guide/LSM/landlock.rst
605 for more details on audit.
606
607 .. _kernel_support:
608
609 Kernel support
610 ==============
611
612 Build time configuration
613 ------------------------
614
615 Landlock was first introduced in Linux 5.13 but it must be configured at build
616 time with ``CONFIG_SECURITY_LANDLOCK=y``. Landlock must also be enabled at boot
617 time like other security modules. The list of security modules enabled by
618 default is set with ``CONFIG_LSM``. The kernel configuration should then
619 contain ``CONFIG_LSM=landlock,[...]`` with ``[...]`` as the list of other
620 potentially useful security modules for the running system (see the
621 ``CONFIG_LSM`` help).
622
623 Boot time configuration
624 -----------------------
625
626 If the running kernel does not have ``landlock`` in ``CONFIG_LSM``, then we can
627 enable Landlock by adding ``lsm=landlock,[...]`` to
628 Documentation/admin-guide/kernel-parameters.rst in the boot loader
629 configuration.
630
631 For example, if the current built-in configuration is:
632
633 .. code-block:: console
634
635 $ zgrep -h "^CONFIG_LSM=" "/boot/config-$(uname -r)" /proc/config.gz 2>/dev/null
636 CONFIG_LSM="lockdown,yama,integrity,apparmor"
637
638 ...and if the cmdline doesn't contain ``landlock`` either:
639
640 .. code-block:: console
641
642 $ sed -n 's/.*\(\<lsm=\S\+\).*/\1/p' /proc/cmdline
643 lsm=lockdown,yama,integrity,apparmor
644
645 ...we should configure the boot loader to set a cmdline extending the ``lsm``
646 list with the ``landlock,`` prefix::
647
648 lsm=landlock,lockdown,yama,integrity,apparmor
649
650 After a reboot, we can check that Landlock is up and running by looking at
651 kernel logs:
652
653 .. code-block:: console
654
655 # dmesg | grep landlock || journalctl -kb -g landlock
656 [ 0.000000] Command line: [...] lsm=landlock,lockdown,yama,integrity,apparmor
657 [ 0.000000] Kernel command line: [...] lsm=landlock,lockdown,yama,integrity,apparmor
658 [ 0.000000] LSM: initializing lsm=lockdown,capability,landlock,yama,integrity,apparmor
659 [ 0.000000] landlock: Up and running.
660
661 The kernel may be configured at build time to always load the ``lockdown`` and
662 ``capability`` LSMs. In that case, these LSMs will appear at the beginning of
663 the ``LSM: initializing`` log line as well, even if they are not configured in
664 the boot loader.
665
666 Network support
667 ---------------
668
669 To be able to explicitly allow TCP operations (e.g., adding a network rule with
670 ``LANDLOCK_ACCESS_NET_BIND_TCP``), the kernel must support TCP
671 (``CONFIG_INET=y``). Otherwise, sys_landlock_add_rule() returns an
672 ``EAFNOSUPPORT`` error, which can safely be ignored because this kind of TCP
673 operation is already not possible.
674
675 Questions and answers
676 =====================
677
678 What about user space sandbox managers?
679 ---------------------------------------
680
681 Using user space processes to enforce restrictions on kernel resources can lead
682 to race conditions or inconsistent evaluations (i.e. `Incorrect mirroring of
683 the OS code and state
684 <https://www.ndss-symposium.org/ndss2003/traps-and-pitfalls-practical-problems-system-call-interposition-based-security-tools/>`_).
685
686 What about namespaces and containers?
687 -------------------------------------
688
689 Namespaces can help create sandboxes but they are not designed for
690 access-control and then miss useful features for such use case (e.g. no
691 fine-grained restrictions). Moreover, their complexity can lead to security
692 issues, especially when untrusted processes can manipulate them (cf.
693 `Controlling access to user namespaces <https://lwn.net/Articles/673597/>`_).
694
695 How to disable Landlock audit records?
696 --------------------------------------
697
698 You might want to put in place filters as explained here:
699 Documentation/admin-guide/LSM/landlock.rst
700
701 Additional documentation
702 ========================
703
704 * Documentation/admin-guide/LSM/landlock.rst
705 * Documentation/security/landlock.rst
706 * https://landlock.io
707
708 .. Links
709 .. _samples/landlock/sandboxer.c:
710 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/samples/landlock/sandboxer.c
711

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

개요와 지원 확인

1-27

이 문서는 GPL-2.0 라이선스로 제공되며 Mickaël Salaün, ANSSI, Microsoft Corporation의 저작권 고지를 포함합니다. 저자는 Mickaël Salaün이고 문서 날짜는 2025년 3월입니다.

Landlock의 목표는 여러 프로세스가 가진 주변 권한, 예를 들어 전역 파일시스템 또는 네트워크 접근을 제한할 수 있게 하는 것입니다. Landlock은 다른 LSM과 함께 쌓을 수 있는 stackable LSM이므로 기존 시스템 전역 접근 제어 위에 새 보안 계층으로 안전한 sandbox를 만들 수 있습니다.

이 sandbox는 사용자 공간 응용 프로그램의 버그나 예상하지 못한 동작, 악의적 동작이 미치는 보안 영향을 줄이기 위한 것입니다. 권한 없는 프로세스를 포함한 어떤 프로세스든 자신의 권한을 안전하게 제한할 수 있습니다.

실행 중인 시스템에서는 root로 `dmesg | grep landlock || journalctl -kb -g landlock`를 실행해 kernel log에 `landlock: Up and running`이 있는지 확인할 수 있습니다. 개발자는 `landlock_create_ruleset()`을 이용한 ABI 조회로도 지원 여부를 확인할 수 있으며, 지원되지 않으면 뒤의 kernel 설정 절차를 따라야 합니다.

Landlock의 역할
항목설명
제한 대상파일시스템·네트워크 같은 주변 권한
LSM 특성기존 시스템 전역 접근 제어 위에 stack 가능
사용 주체권한 없는 프로세스를 포함한 모든 프로세스
로그 확인landlock: Up and running
프로그램 확인landlock_create_ruleset() ABI 조회

기존 접근 제어를 대체하지 않고 프로세스가 스스로 추가 제한을 쌓는 구조입니다.

.. SPDX-License-Identifier: GPL-2.0
.. Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net>
.. Copyright © 2019-2020 ANSSI
.. Copyright © 2021-2022 Microsoft Corporation

=====================================
Landlock: unprivileged access control
=====================================

:Author: Mickaël Salaün
:Date: March 2025

The goal of Landlock is to enable restriction of ambient rights (e.g. global
filesystem or network access) for a set of processes.  Because Landlock
is a stackable LSM, it makes it 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.

We can quickly make sure that Landlock is enabled in the running system by
looking for "landlock: Up and running" in kernel logs (as root):
``dmesg | grep landlock || journalctl -kb -g landlock`` .
Developers can also easily check for Landlock support with a
:ref:`related system call <landlock_abi_versions>`.
If Landlock is not currently supported, we need to
:ref:`configure the kernel appropriately <kernel_support>`.

규칙 유형과 정책 모델

28-60

Landlock 규칙은 프로세스가 어떤 객체에 수행하려는 동작을 기술합니다. 여러 규칙은 ruleset으로 모이며, 이 ruleset은 이를 강제한 thread와 이후 생성되는 자식들을 제한합니다.

현재 규칙 유형은 두 가지입니다. Filesystem 규칙의 객체는 파일 계층이고 동작은 filesystem access right로 표현합니다. ABI v4부터 제공되는 network 규칙의 객체는 TCP port이며 동작은 network access right로 표현합니다.

예제 정책은 파일시스템 읽기와 특정 TCP 연결만 허용합니다. 파일시스템 쓰기와 그 밖의 TCP 동작은 거부합니다.

ruleset은 제한하려는 파일시스템 동작과 네트워크 동작을 모두 명시적으로 처리해야 합니다. kernel과 사용자 공간이 서로 어느 제한을 지원하는지 모를 수 있으므로, 하위·상위 호환성을 위해 기본 거부할 access right를 명시하는 계약이 필요합니다.

Landlock 규칙 유형
항목설명
Filesystem 규칙파일 계층 + filesystem access rights
Network 규칙TCP port + network access rights, ABI v4부터
예제의 허용파일시스템 읽기와 HTTPS 연결
예제의 거부파일시스템 쓰기와 다른 TCP 동작
handled right지원 차이를 다루기 위한 명시적 기본 거부 범위

규칙의 객체와 권한 집합을 구분합니다.

정책 구성의 큰 흐름
handled_access_fs·handled_access_net·scoped 선언실행 중 kernel의 Landlock ABI 조회지원하지 않는 권한 제거ruleset 생성허용 규칙 추가PR_SET_NO_NEW_PRIVS 설정landlock_restrict_self()로 강제

처리할 권한을 선언한 뒤 예외 규칙을 추가하고 현재 thread에 강제합니다.


Landlock rules
==============

A Landlock rule describes an action on an object which the process intends to
perform.  A set of rules is aggregated in a ruleset, which can then restrict
the thread enforcing it, and its future children.

The two existing types of rules are:

Filesystem rules
    For these rules, the object is a file hierarchy,
    and the related filesystem actions are defined with
    `filesystem access rights`.

Network rules (since ABI v4)
    For these rules, the object is a TCP port,
    and the related actions are defined with `network access rights`.

Defining and enforcing a security policy
----------------------------------------

We first need to define the ruleset that will contain our rules.

For this example, the ruleset will contain rules that only allow filesystem
read actions and establish a specific TCP connection. Filesystem write
actions and other TCP actions will be denied.

The ruleset then needs to handle both these kinds of actions.  This is
required for backward and forward compatibility (i.e. the kernel and user
space may not know each other's supported restrictions), hence the need
to be explicit about the denied-by-default access rights.

처리 권한 선언과 ABI별 필터링

61-131

`struct landlock_ruleset_attr`의 `handled_access_fs`에는 실행, 파일 쓰기·읽기, 디렉터리 읽기, 디렉터리·파일 제거, 여러 inode 유형 생성, 참조, truncate, device ioctl 권한을 넣습니다.

`handled_access_net`에는 `LANDLOCK_ACCESS_NET_BIND_TCP`와 `LANDLOCK_ACCESS_NET_CONNECT_TCP`를 넣고, `scoped`에는 `LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET`과 `LANDLOCK_SCOPE_SIGNAL`을 넣습니다. 이는 규칙으로 허용하지 않은 해당 동작을 기본 거부하겠다는 선언입니다.

응용 프로그램이 어느 kernel version에서 실행될지 알 수 없으므로 best-effort 보안을 따르는 편이 안전합니다. 사용 중인 kernel에서 가능한 기능만 사용하되, 가능한 범위에서는 사용자를 최대한 보호해야 합니다.

`landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION)`으로 ABI version을 조회합니다. Landlock을 처리할 수 없으면 예제는 오류를 알리고 제한 없이 정상 종료하는 방식으로 기능을 점진적으로 낮춥니다.

ABI 1에서는 ABI 2부터 생긴 `LANDLOCK_ACCESS_FS_REFER`를 제거하고, ABI 2에서는 ABI 3부터 생긴 `LANDLOCK_ACCESS_FS_TRUNCATE`를 제거합니다. ABI 3에서는 ABI 4부터 생긴 TCP bind·connect 권한을 제거합니다.

ABI 4에서는 ABI 5부터 생긴 `LANDLOCK_ACCESS_FS_IOCTL_DEV`를 제거하고, ABI 5에서는 ABI 6부터 생긴 두 `LANDLOCK_SCOPE_*` bit를 제거합니다. `switch`의 의도적인 fallthrough는 현재 ABI보다 나중에 추가된 기능을 모두 제거합니다.

ABI별 사용할 수 없는 기능 제거
항목설명
ABI 1LANDLOCK_ACCESS_FS_REFER 제거
ABI 2LANDLOCK_ACCESS_FS_TRUNCATE 제거
ABI 3BIND_TCP·CONNECT_TCP 제거
ABI 4LANDLOCK_ACCESS_FS_IOCTL_DEV 제거
ABI 5ABSTRACT_UNIX_SOCKET·SIGNAL scope 제거
ABI 6 이상예제에 선언된 모든 handled right와 scope 사용

조회한 ABI가 오래될수록 이후 ABI에서 추가된 bit를 ruleset attribute에서 제거합니다.

Best-effort ABI 협상
VERSION flag로 ABI 조회조회 실패면 graceful degradation현재 ABI 확인더 새로운 access right 제거더 새로운 scope 제거호환되는 ruleset_attr 완성

새 사용자 공간이 오래된 kernel에서도 지원되는 보호를 포기하지 않도록 구성합니다.

.. code-block:: c

    struct landlock_ruleset_attr ruleset_attr = {
        .handled_access_fs =
            LANDLOCK_ACCESS_FS_EXECUTE |
            LANDLOCK_ACCESS_FS_WRITE_FILE |
            LANDLOCK_ACCESS_FS_READ_FILE |
            LANDLOCK_ACCESS_FS_READ_DIR |
            LANDLOCK_ACCESS_FS_REMOVE_DIR |
            LANDLOCK_ACCESS_FS_REMOVE_FILE |
            LANDLOCK_ACCESS_FS_MAKE_CHAR |
            LANDLOCK_ACCESS_FS_MAKE_DIR |
            LANDLOCK_ACCESS_FS_MAKE_REG |
            LANDLOCK_ACCESS_FS_MAKE_SOCK |
            LANDLOCK_ACCESS_FS_MAKE_FIFO |
            LANDLOCK_ACCESS_FS_MAKE_BLOCK |
            LANDLOCK_ACCESS_FS_MAKE_SYM |
            LANDLOCK_ACCESS_FS_REFER |
            LANDLOCK_ACCESS_FS_TRUNCATE |
            LANDLOCK_ACCESS_FS_IOCTL_DEV,
        .handled_access_net =
            LANDLOCK_ACCESS_NET_BIND_TCP |
            LANDLOCK_ACCESS_NET_CONNECT_TCP,
        .scoped =
            LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
            LANDLOCK_SCOPE_SIGNAL,
    };

Because we may not know which kernel version an application will be executed
on, it is safer to follow a best-effort security approach.  Indeed, we
should try to protect users as much as possible whatever the kernel they are
using.

To be compatible with older Linux versions, we detect the available Landlock ABI
version, and only use the available subset of access rights:

.. code-block:: c

    int abi;

    abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
    if (abi < 0) {
        /* Degrades gracefully if Landlock is not handled. */
        perror("The running kernel does not enable to use Landlock");
        return 0;
    }
    switch (abi) {
    case 1:
        /* Removes LANDLOCK_ACCESS_FS_REFER for ABI < 2 */
        ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER;
        __attribute__((fallthrough));
    case 2:
        /* Removes LANDLOCK_ACCESS_FS_TRUNCATE for ABI < 3 */
        ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
        __attribute__((fallthrough));
    case 3:
        /* Removes network support for ABI < 4 */
        ruleset_attr.handled_access_net &=
            ~(LANDLOCK_ACCESS_NET_BIND_TCP |
              LANDLOCK_ACCESS_NET_CONNECT_TCP);
        __attribute__((fallthrough));
    case 4:
        /* Removes LANDLOCK_ACCESS_FS_IOCTL_DEV for ABI < 5 */
        ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_IOCTL_DEV;
        __attribute__((fallthrough));
    case 5:
        /* Removes LANDLOCK_SCOPE_* for ABI < 6 */
        ruleset_attr.scoped &= ~(LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
                                 LANDLOCK_SCOPE_SIGNAL);
    }

ruleset 생성과 파일 계층 규칙

132-180

ABI에 맞게 정리한 attribute를 `landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0)`에 넘겨 포괄적인 ruleset을 만들고 `ruleset_fd`를 받습니다. 실패하면 정책을 강제할 수 없으므로 오류로 종료합니다.

반환된 file descriptor가 ruleset을 가리키므로 이제 규칙을 추가할 수 있습니다. 예제의 첫 규칙은 `/usr` 파일 계층에 대한 읽기만 허용합니다. 다른 규칙이 없다면 handled set에 포함된 쓰기 동작은 거부됩니다.

`struct landlock_path_beneath_attr`의 `allowed_access`에는 `LANDLOCK_ACCESS_FS_EXECUTE`, `LANDLOCK_ACCESS_FS_READ_FILE`, `LANDLOCK_ACCESS_FS_READ_DIR`을 설정합니다.

`/usr`는 `O_PATH | O_CLOEXEC`로 열어 `parent_fd`에 저장합니다. 이 descriptor와 `LANDLOCK_RULE_PATH_BENEATH`를 `landlock_add_rule()`에 전달한 뒤 `parent_fd`를 닫습니다. 규칙 추가 실패 시 ruleset descriptor도 닫고 종료합니다.

규칙의 `allowed_access` 역시 ruleset 생성 때와 같은 방식으로 Landlock ABI에 따라 걸러야 할 수 있습니다. 하지만 이 예제에서 요청한 세 filesystem 권한은 모두 ABI 1부터 있으므로 별도 필터링이 필요하지 않습니다.

파일 계층 규칙
항목설명
ruleset 생성landlock_create_ruleset() -> ruleset_fd
객체/usr 파일 계층
parent_fdopen(/usr, O_PATH | O_CLOEXEC)
rule typeLANDLOCK_RULE_PATH_BENEATH
허용EXECUTE·READ_FILE·READ_DIR
그 밖의 handled 권한규칙이 없으므로 거부

`/usr` 읽기 허용 규칙의 핵심 값입니다.

PATH_BENEATH 규칙 추가
ruleset_fd 생성/usr를 O_PATH로 열기landlock_path_beneath_attr 작성landlock_add_rule() 호출parent_fd 닫기성공 시 다음 규칙으로 진행

경로 descriptor는 규칙 추가가 끝난 직후 닫아도 됩니다.

This enables the creation of an inclusive ruleset that will contain our rules.

.. code-block:: c

    int ruleset_fd;

    ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
    if (ruleset_fd < 0) {
        perror("Failed to create a ruleset");
        return 1;
    }

We can now add a new rule to this ruleset thanks to the returned file
descriptor referring to this ruleset.  The rule will only allow reading the
file hierarchy ``/usr``.  Without another rule, write actions would then be
denied by the ruleset.  To add ``/usr`` to the ruleset, we open it with the
``O_PATH`` flag and fill the &struct landlock_path_beneath_attr with this file
descriptor.

.. code-block:: c

    int err;
    struct landlock_path_beneath_attr path_beneath = {
        .allowed_access =
            LANDLOCK_ACCESS_FS_EXECUTE |
            LANDLOCK_ACCESS_FS_READ_FILE |
            LANDLOCK_ACCESS_FS_READ_DIR,
    };

    path_beneath.parent_fd = open("/usr", O_PATH | O_CLOEXEC);
    if (path_beneath.parent_fd < 0) {
        perror("Failed to open file");
        close(ruleset_fd);
        return 1;
    }
    err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
                            &path_beneath, 0);
    close(path_beneath.parent_fd);
    if (err) {
        perror("Failed to update ruleset");
        close(ruleset_fd);
        return 1;
    }

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
ABI version.  In this example, this is not required because all of the requested
``allowed_access`` rights are already available in ABI 1.

네트워크 규칙과 정책 강제

181-226

네트워크 접근 제어에서는 특정 동작에 사용할 port 번호를 허용하는 규칙을 추가할 수 있습니다. 예제는 HTTPS 연결을 허용합니다.

`struct landlock_net_port_attr`에 `LANDLOCK_ACCESS_NET_CONNECT_TCP`와 port `443`을 넣고 `LANDLOCK_RULE_NET_PORT` 유형으로 `landlock_add_rule()`을 호출합니다.

이 시점의 ruleset에는 `/usr` 읽기를 허용하면서 그 밖의 handled filesystem 접근을 거부하는 규칙과, HTTPS 연결을 허용하는 규칙이 들어 있습니다.

현재 thread가 SUID binary 등을 통해 더 많은 권한을 얻지 못하도록 먼저 `prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)`을 설정해야 합니다. 실패하면 ruleset descriptor를 닫고 종료합니다.

그 다음 `landlock_restrict_self(ruleset_fd, 0)`을 호출하여 현재 thread를 sandbox에 넣고, 성공 여부와 관계없이 적절한 시점에 `ruleset_fd`를 닫습니다.

호출이 성공하면 정책은 현재 thread와 이후 생성되는 모든 자식에 강제됩니다. Landlock 정책은 제거할 수 없으며 새 제한만 더할 수 있습니다. 새 domain은 기존 parent domain이 있으면 그것과 새 ruleset을 병합한 결과입니다.

전체 동작 예제는 `samples/landlock/sandboxer.c`에서 확인할 수 있습니다.

HTTPS 허용과 강제
항목설명
net ruleCONNECT_TCP, port 443
권한 상승 방지PR_SET_NO_NEW_PRIVS
정책 강제landlock_restrict_self()
적용 대상현재 thread와 이후 자식
정책 변경제거 불가, 더 강한 제한만 추가

네트워크 예외를 추가한 뒤 권한 상승을 막고 정책을 적용합니다.

Landlock domain 진입
filesystem·network 규칙 완성PR_SET_NO_NEW_PRIVSlandlock_restrict_self()기존 parent domain과 병합현재 thread 제한향후 자식에게 상속

기존 domain과 새 ruleset의 제한이 합쳐진 새 domain으로 이동합니다.

For network access-control, we can add a set of rules that allow to use a port
number for a specific action: HTTPS connections.

.. code-block:: c

    struct landlock_net_port_attr net_port = {
        .allowed_access = LANDLOCK_ACCESS_NET_CONNECT_TCP,
        .port = 443,
    };

    err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
                            &net_port, 0);

The next step is to restrict the current thread from gaining more privileges
(e.g. through a SUID binary).  We now have a ruleset with the first rule
allowing read access to ``/usr`` while denying all other handled accesses for
the filesystem, and a second rule allowing HTTPS connections.

.. code-block:: c

    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
        perror("Failed to restrict privileges");
        close(ruleset_fd);
        return 1;
    }

The current thread is now ready to sandbox itself with the ruleset.

.. code-block:: c

    if (landlock_restrict_self(ruleset_fd, 0)) {
        perror("Failed to enforce ruleset");
        close(ruleset_fd);
        return 1;
    }
    close(ruleset_fd);

If the ``landlock_restrict_self`` system call succeeds, the current thread is
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
security policy; only adding more restrictions is allowed.  These threads are
now in a new Landlock domain, which is a merger of their parent one (if any)
with the new ruleset.

Full working code can be found in `samples/landlock/sandboxer.c`_.

파일 계층 설계 모범 사례

227-249

가능한 한 파일 계층의 leaf에 access right를 설정하는 것이 좋습니다. 예를 들어 `~/` 전체를 read-only로 두고 `~/tmp/`만 read-write로 두기보다 `~/doc/`을 read-only, `~/tmp/`를 read-write로 각각 설정하는 편이 낫습니다.

이 방식은 상위 디렉터리 위치에 의존하지 않는 자급적인 계층을 만듭니다. 특히 link나 rename을 허용할 때 디렉터리별 권한이 일관되면, 작업 자체에 필요한 권한을 제외하고 destination directory의 우연한 권한에 기대지 않고 디렉터리를 옮길 수 있습니다. 관련 세부 사항은 `LANDLOCK_ACCESS_FS_REFER` 문서를 참조합니다.

자급적인 계층은 필요한 access right를 최소 데이터 집합으로 좁히는 데도 도움이 됩니다.

또한 데이터는 들어올 수 있지만 나갈 수 없는 sinkhole directory를 피하는 데 도움이 됩니다. 다만 실제 데이터 배치는 개발자가 통제하지 못할 수 있습니다.

그런 경우 `~/tmp/`에 write-only가 아니라 read-write를 부여하면, `~/tmp/`가 읽을 수 없는 디렉터리 아래로 옮겨져도 그 내용을 계속 나열할 수 있습니다.

계층 권한 설계
항목설명
권장~/doc/ read-only + ~/tmp/ read-write
덜 권장~/ read-only + ~/tmp/ read-write
장점위치 독립성, 최소 권한, rename·link 일관성
주의sinkhole directory와 통제할 수 없는 데이터 배치

상위 경로보다 실제 데이터 leaf에 독립적인 권한을 부여합니다.

Good practices
--------------

It is recommended to set access rights to file hierarchy leaves as much as
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
``~/`` as a read-only hierarchy and ``~/tmp/`` as a read-write hierarchy.
Following this good practice leads to self-sufficient hierarchies that do not
depend on their location (i.e. parent directories).  This is particularly
relevant when we want to allow linking or renaming.  Indeed, having consistent
access rights per directory enables changing the location of such directories
without relying on the destination directory access rights (except those that
are required for this operation, see ``LANDLOCK_ACCESS_FS_REFER``
documentation).

Having self-sufficient hierarchies also helps to tighten the required access
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,
this depends on data organization, which might not be controlled by developers.
In this case, granting read-write access to ``~/tmp/``, instead of write-only
access, would potentially allow moving ``~/tmp/`` to a non-readable directory
and still keep the ability to list the content of ``~/tmp/``.

정책 계층, bind mount와 OverlayFS

250-289

thread가 자신에게 ruleset을 강제할 때마다 Landlock domain에 새 정책 계층이 추가됩니다. 이 보완 정책은 이미 thread를 제한하는 다른 ruleset 위에 쌓이므로 sandbox된 thread도 새 ruleset으로 자신을 더 제한할 수 있습니다.

하나의 정책 계층에서는 경로에서 만난 규칙 중 하나 이상이 접근을 허용하면 그 계층이 접근을 허용합니다. 즉 같은 계층의 규칙은 허용 관점에서 합집합처럼 동작합니다.

실제 접근은 강제된 모든 정책 계층이 허용하고, filesystem DAC와 다른 LSM 정책 같은 시스템의 모든 접근 제어도 허용해야 가능합니다. 계층 사이는 교집합처럼 동작합니다.

Landlock은 파일 계층에 접근 권한을 연결합니다. 이 권한은 bind mount에는 전파될 수 있지만 OverlayFS에는 같은 방식으로 전파되지 않습니다.

bind mount는 source 파일 계층을 destination에 그대로 비춥니다. destination은 정확히 같은 파일들로 구성되므로 Landlock 규칙을 source 또는 destination 경로 어느 쪽으로도 연결할 수 있습니다.

규칙은 경로에서 만날 때 접근을 제한하므로 bind mount 결과인지 여부와 무관하게 여러 파일 계층을 동시에 제한할 수 있습니다.

OverlayFS mount point는 upper·lower layer를 merge directory에 결합하고 그 결과를 mount point에 공개합니다. merge 계층의 수정은 upper layer에만 반영됩니다.

Landlock 관점에서 각 OverlayFS layer와 merge hierarchy는 서로 독립적인 파일·디렉터리 집합입니다. layer를 제한해도 merge 결과를 제한하지 않으며 반대도 마찬가지입니다. 사용자는 기반 filesystem 구현보다 실제로 접근을 허용할 파일 계층 각각을 기준으로 정책을 세워야 합니다.

정책 결합과 mount 의미
항목설명
한 계층 안경로에서 만난 규칙 하나 이상이 허용
여러 Landlock 계층모든 계층이 허용해야 접근 가능
다른 접근 제어DAC와 다른 LSM도 모두 허용 필요
bind mountsource와 destination이 같은 파일 객체를 공유
OverlayFSupper·lower·merge가 Landlock상 독립 계층

규칙·계층·filesystem 종류에 따라 권한이 결합되는 방식을 구분합니다.

최종 경로 접근 판정
요청 경로 순회각 Landlock 계층에서 허용 규칙 탐색계층별 하나 이상 허용모든 Landlock 계층 허용filesystem DAC 허용다른 LSM 허용최종 접근 허용

한 계층 안의 허용을 구한 뒤 모든 보안 계층의 결과를 함께 확인합니다.

Layers of file path access rights
---------------------------------

Each time a thread enforces a ruleset on itself, it updates its Landlock domain
with a new layer of policy.  This complementary policy is stacked with any
other rulesets potentially already restricting this thread.  A sandboxed thread
can then safely add more constraints to itself with a new enforced ruleset.

One policy layer grants access to a file path if at least one of its rules
encountered on the path grants the access.  A sandboxed thread can only access
a file path if all its enforced policy layers grant the access as well as all
the other system access controls (e.g. filesystem DAC, other LSM policies,
etc.).

Bind mounts and OverlayFS
-------------------------

Landlock enables restricting access to file hierarchies, which means that these
access rights can be propagated with bind mounts (cf.
Documentation/filesystems/sharedsubtree.rst) but not with
Documentation/filesystems/overlayfs.rst.

A bind mount mirrors a source file hierarchy to a destination.  The destination
hierarchy is then composed of the exact same files, on which Landlock rules can
be tied, either via the source or the destination path.  These rules restrict
access when they are encountered on a path, which means that they can restrict
access to multiple file hierarchies at the same time, whether these hierarchies
are the result of bind mounts or not.

An OverlayFS mount point consists of upper and lower layers.  These layers are
combined in a merge directory, and that merged directory becomes available at
the mount point.  This merge hierarchy may include files from the upper and
lower layers, but modifications performed on the merge hierarchy only reflect
on the upper layer.  From a Landlock policy point of view, all OverlayFS layers
and merge hierarchies are standalone and each contains their own set of files
and directories, which is different from bind mounts.  A policy restricting an
OverlayFS layer will not restrict the resulted merged hierarchy, and vice versa.
Landlock users should then only think about file hierarchies they want to allow
access to, regardless of the underlying filesystem.

상속, ptrace와 IPC 범위

290-346

`clone(2)`으로 생긴 새 thread는 parent의 Landlock domain 제한을 상속합니다. 이는 seccomp 또는 task의 `credentials(7)`를 다루는 다른 LSM의 상속과 비슷합니다.

한 process의 특정 thread가 자신에게 Landlock 규칙을 적용해도 sibling thread에는 자동 적용되지 않습니다. 이 점은 POSIX thread credential 변경과 다르며 `nptl(7)`의 설명을 참고해야 합니다.

thread가 자신을 sandbox하면 관련 정책이 그 모든 descendant에 계속 강제됨이 보장됩니다. 따라서 응용 프로그램별 독립적이고 모듈화된 보안 정책을 만들 수 있고, 실행 시점 parent 정책에 따라 자동 조합됩니다.

sandbox process는 sandbox되지 않은 process보다 권한이 적으므로 다른 process를 조작할 때 추가 제한을 받습니다. target에 `ptrace(2)`와 관련 syscall을 사용하려면 tracer가 tracee의 access right를 모두 포함하는 superset이어야 합니다. 다시 말해 tracee가 tracer의 sub-domain에 있어야 합니다.

명시적인 IPC scoping은 sandbox 사이의 상호 작용을 더 줄입니다. ruleset 생성 시 특정 동작의 scope를 제한하면 같은 Landlock domain 또는 nested domain의 process까지만 도달할 수 있습니다.

`LANDLOCK_SCOPE_SIGNAL`은 같은 domain이나 nested domain에서 실행되는 target process에만 signal을 보낼 수 있게 제한합니다.

`LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET`은 같은 domain이나 nested domain의 process가 만든 abstract `unix(7)` socket address에만 `connect(2)`할 수 있게 제한합니다.

연결되지 않은 datagram socket에서 `sendto(2)`를 호출하면 암시적 `connect(2)`처럼 취급하므로 remote endpoint가 같은 domain 또는 nested domain에서 오지 않았다면 차단합니다.

이미 연결된 socket에서 `sendto(2)`를 호출하는 경우에는 제한하지 않습니다. 이 동작은 datagram과 stream socket 모두에 적용됩니다.

IPC scoping에는 `landlock_add_rule(2)`로 예외를 추가할 수 없습니다. domain에서 동작이 scoped되면 scope 밖의 resource나 process를 허용하는 규칙은 만들 수 없습니다.

Process 간 제한
항목설명
clone 자식parent Landlock domain 상속
sibling thread자동 적용되지 않음
ptracetracer 권한이 tracee 권한의 superset이어야 함
SIGNAL scope같은 domain 또는 nested domain만
ABSTRACT_UNIX_SOCKET scope같은 domain 또는 nested domain이 만든 address만
scope 예외landlock_add_rule()로 추가 불가

상속과 대상 domain 관계가 허용 범위를 결정합니다.

Domain 관계와 IPC
tracer 또는 IPC sender domaintarget domain 관계 확인같은 domain이면 허용 후보target이 nested domain이면 허용 후보상위·무관 domain이면 거부다른 시스템 접근 제어도 평가

동일·하위 domain 방향으로만 scoped 동작을 허용합니다.

Inheritance
-----------

Every new thread resulting from a :manpage:`clone(2)` inherits Landlock domain
restrictions from its parent.  This is similar to seccomp inheritance (cf.
Documentation/userspace-api/seccomp_filter.rst) or any other LSM dealing with
task's :manpage:`credentials(7)`.  For instance, one process's thread may apply
Landlock rules to itself, but they will not be automatically applied to other
sibling threads (unlike POSIX thread credential changes, cf.
:manpage:`nptl(7)`).

When a thread sandboxes itself, we have the guarantee that the related security
policy will stay enforced on all this thread's descendants.  This allows
creating standalone and modular security policies per application, which will
automatically be composed between themselves according to their runtime parent
policies.

Ptrace restrictions
-------------------

A sandboxed process has less privileges than a non-sandboxed process and must
then be subject to additional restrictions when manipulating another process.
To be allowed to use :manpage:`ptrace(2)` and related syscalls on a target
process, a sandboxed process should have a superset of the target process's
access rights, which means the tracee must be in a sub-domain of the tracer.

IPC scoping
-----------

Similar to the implicit `Ptrace restrictions`_, we may want to further restrict
interactions between sandboxes.  Therefore, at ruleset creation time, each
Landlock domain can restrict the scope for certain operations, so that these
operations can only reach out to processes within the same Landlock domain or in
a nested Landlock domain (the "scope").

The operations which can be scoped are:

``LANDLOCK_SCOPE_SIGNAL``
    This limits the sending of signals to target processes which run within the
    same or a nested Landlock domain.

``LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET``
    This limits the set of abstract :manpage:`unix(7)` sockets to which we can
    :manpage:`connect(2)` to socket addresses which were created by a process in
    the same or a nested Landlock domain.

    A :manpage:`sendto(2)` on a non-connected datagram socket is treated as if
    it were doing an implicit :manpage:`connect(2)` and will be blocked if the
    remote end does not stem from the same or a nested Landlock domain.

    A :manpage:`sendto(2)` on a socket which was previously connected will not
    be restricted.  This works for both datagram and stream sockets.

IPC scoping does not support exceptions via :manpage:`landlock_add_rule(2)`.
If an operation is scoped within a domain, no rules can be added to allow access
to resources or processes outside of the scope.

파일 truncate와 file descriptor 권한

347-385

`LANDLOCK_ACCESS_FS_WRITE_FILE`과 `LANDLOCK_ACCESS_FS_TRUNCATE`가 다루는 동작은 모두 파일 내용을 바꾸며 직관적이지 않게 겹칠 수 있습니다. 두 권한은 항상 함께 명시하는 것이 권장됩니다.

`creat(2)`는 이름만 보면 파일 생성과 쓰기 권한만 필요할 것 같지만, 같은 이름의 기존 파일이 있으면 truncate 권한도 필요합니다.

반대로 파일 truncate에 `LANDLOCK_ACCESS_FS_WRITE_FILE`이 필요한 것은 아닙니다. `truncate(2)`뿐 아니라 `open(2)`에 `O_RDONLY | O_TRUNC`를 지정해서도 내용을 자를 수 있습니다.

truncate 권한은 열린 파일에 연결됩니다.

파일을 열 때 사용 가능했던 `LANDLOCK_ACCESS_FS_TRUNCATE`와 `LANDLOCK_ACCESS_FS_IOCTL_DEV` 권한은 새 file descriptor에 결합되고, 이후 `ftruncate(2)`와 `ioctl(2)` 시도에 사용됩니다.

이는 파일을 읽기 또는 쓰기로 열 때 `open(2)`에서 권한을 검사하고 이후 `read(2)`·`write(2)`에서는 다시 검사하지 않는 동작과 비슷합니다.

따라서 같은 파일을 가리키는 여러 file descriptor에 Landlock이 서로 다른 동작을 강제할 수 있습니다. ruleset 강제 전과 후에 각각 연 descriptor를 process가 계속 보유하면 이런 상황이 생깁니다.

이 descriptor를 process 사이에 전달해도 Landlock 속성은 유지됩니다. 전달에 참여한 일부 process에 Landlock ruleset이 강제되지 않았더라도 descriptor에 결합된 속성은 그대로 적용됩니다.

파일 내용 변경 권한
항목설명
WRITE_FILE파일 쓰기
TRUNCATEtruncate·creat 기존 파일·O_TRUNC
권장WRITE_FILE과 TRUNCATE를 함께 지정
FD 결합 권한TRUNCATE·IOCTL_DEV
결합 시점새 파일을 open할 때
FD 전달process 사이 전달 후에도 Landlock 속성 유지

path 기준 검사와 descriptor에 결합되는 권한을 함께 구분해야 합니다.

Descriptor별 권한 차이
ruleset 강제 전 파일 open첫 번째 FD에 당시 권한 결합Landlock ruleset 강제같은 파일 다시 open두 번째 FD에 더 제한된 권한 결합ftruncate·ioctl에서 FD별 결과다른 process에 전달해도 속성 유지

같은 inode라도 open 시점의 domain에 따라 후속 동작이 달라질 수 있습니다.

Truncating files
----------------

The operations covered by ``LANDLOCK_ACCESS_FS_WRITE_FILE`` and
``LANDLOCK_ACCESS_FS_TRUNCATE`` both change the contents of a file and sometimes
overlap in non-intuitive ways.  It is recommended to always specify both of
these together.

A particularly surprising example is :manpage:`creat(2)`.  The name suggests
that this system call requires the rights to create and write files.  However,
it also requires the truncate right if an existing file under the same name is
already present.

It should also be noted that truncating files does not require the
``LANDLOCK_ACCESS_FS_WRITE_FILE`` right.  Apart from the :manpage:`truncate(2)`
system call, this can also be done through :manpage:`open(2)` with the flags
``O_RDONLY | O_TRUNC``.

The truncate right is associated with the opened file (see below).

Rights associated with file descriptors
---------------------------------------

When opening a file, the availability of the ``LANDLOCK_ACCESS_FS_TRUNCATE`` and
``LANDLOCK_ACCESS_FS_IOCTL_DEV`` rights is associated with the newly created
file descriptor and will be used for subsequent truncation and ioctl attempts
using :manpage:`ftruncate(2)` and :manpage:`ioctl(2)`.  The behavior is similar
to opening a file for reading or writing, where permissions are checked during
:manpage:`open(2)`, but not during the subsequent :manpage:`read(2)` and
:manpage:`write(2)` calls.

As a consequence, it is possible that a process has multiple open file
descriptors referring to the same file, but Landlock enforces different things
when operating with these file descriptors.  This can happen when a Landlock
ruleset gets enforced and the process keeps file descriptors which were opened
both before and after the enforcement.  It is also possible to pass such file
descriptors between processes, keeping their Landlock properties, even when some
of the involved processes do not have an enforced Landlock ruleset.

하위·상위 호환성과 ABI 조회

386-437

Landlock은 과거와 미래 kernel version 모두와 호환되도록 설계되었습니다. syscall attribute와 관련 bitflag, 특히 ruleset의 `handled_access_fs`가 이 계약을 가능하게 합니다.

처리할 access right를 명시하면 kernel과 사용자 공간이 서로 분명한 계약을 맺습니다. 시스템 업데이트만으로 sandbox가 갑자기 더 엄격해져 응용 프로그램이 깨지는 일을 막기 위해 필요한 설계입니다.

개발자는 Landlock mailing list를 구독하여 최신 기능에 맞게 응용 프로그램을 의도적으로 업데이트하고 시험할 수 있습니다.

사용자가 서로 다른 kernel version을 쓸 수 있으므로, runtime에 Landlock ABI version을 확인하고 지원되는 기능만 강제하는 best-effort 보안 방식을 강하게 권장합니다.

`landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION)`으로 ABI를 읽습니다. 실패했을 때 `ENOSYS`는 현재 kernel이 Landlock을 지원하지 않음을, `EOPNOTSUPP`는 현재 비활성화되어 있음을 뜻합니다.

조회가 성공하면 반환값으로 기능을 판별할 수 있습니다. 예를 들어 ABI가 2 이상이면 `LANDLOCK_ACCESS_FS_REFER`를 지원합니다. 첫 ABI가 암시적으로 지원하는 kernel interface와 이후 version부터 지원하는 feature는 이어지는 API 문서에 표시됩니다.

ABI 조회 결과
항목설명
호출landlock_create_ruleset(NULL, 0, VERSION)
반환값 >= 1지원 ABI version
ENOSYSkernel에 Landlock syscall 지원 없음
EOPNOTSUPPLandlock이 현재 비활성화
ABI >= 2 예LANDLOCK_ACCESS_FS_REFER 지원

지원되지 않음과 비활성화 상태를 구분합니다.

Compatibility
=============

Backward and forward compatibility
----------------------------------

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
associated bitflags, particularly the ruleset's ``handled_access_fs``.  Making
handled access rights explicit enables the kernel and user space to have a clear
contract with each other.  This is required to make sure sandboxing will not
get stricter with a system update, which could break applications.

Developers can subscribe to the `Landlock mailing list
<https://subspace.kernel.org/lists.linux.dev.html>`_ to knowingly update and
test their applications with the latest available features.  In the interest of
users, and because they may use different kernel versions, it is strongly
encouraged to follow a best-effort security approach by checking the Landlock
ABI version at runtime and only enforcing the supported features.

.. _landlock_abi_versions:

Landlock ABI versions
---------------------

The Landlock ABI version can be read with the sys_landlock_create_ruleset()
system call:

.. code-block:: c

    int abi;

    abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
    if (abi < 0) {
        switch (errno) {
        case ENOSYS:
            printf("Landlock is not supported by the current kernel.\n");
            break;
        case EOPNOTSUPP:
            printf("Landlock is currently disabled.\n");
            break;
        }
        return 0;
    }
    if (abi >= 2) {
        printf("Landlock supports LANDLOCK_ACCESS_FS_REFER.\n");
    }

The following kernel interfaces are implicitly supported by the first ABI
version.  Features only supported from a specific version are explicitly marked
as such.

Kernel interface 문서

438-471

이 절은 Landlock kernel interface의 실제 kernel-doc을 소스에서 포함합니다. access right는 `include/uapi/linux/landlock.h`의 `fs_access`, `net_access`, `scope` 식별자에서 생성됩니다.

새 ruleset 생성 syscall 설명은 `security/landlock/syscalls.c`의 `sys_landlock_create_ruleset`에서 가져옵니다.

ruleset attribute 구조체 설명은 `include/uapi/linux/landlock.h`의 `landlock_ruleset_attr`에서 가져옵니다.

ruleset 확장 syscall 설명은 `security/landlock/syscalls.c`의 `sys_landlock_add_rule`에서 가져옵니다.

규칙 유형과 attribute는 `include/uapi/linux/landlock.h`의 `landlock_rule_type`, `landlock_path_beneath_attr`, `landlock_net_port_attr`에서 가져옵니다.

ruleset 강제 syscall 설명은 `security/landlock/syscalls.c`의 `sys_landlock_restrict_self`에서 가져옵니다.

kernel-doc 소스
항목설명
Access rightsinclude/uapi/linux/landlock.h: fs_access, net_access, scope
Create rulesetsecurity/landlock/syscalls.c: sys_landlock_create_ruleset
Ruleset attributeinclude/uapi/linux/landlock.h: landlock_ruleset_attr
Add rulesecurity/landlock/syscalls.c: sys_landlock_add_rule
Rule attributeslandlock_rule_type, landlock_path_beneath_attr, landlock_net_port_attr
Restrict selfsecurity/landlock/syscalls.c: sys_landlock_restrict_self

Sphinx가 API 설명을 가져오는 source path와 identifier입니다.

Kernel interface
================

Access rights
-------------

.. kernel-doc:: include/uapi/linux/landlock.h
    :identifiers: fs_access net_access scope

Creating a new ruleset
----------------------

.. kernel-doc:: security/landlock/syscalls.c
    :identifiers: sys_landlock_create_ruleset

.. kernel-doc:: include/uapi/linux/landlock.h
    :identifiers: landlock_ruleset_attr

Extending a ruleset
-------------------

.. kernel-doc:: security/landlock/syscalls.c
    :identifiers: sys_landlock_add_rule

.. kernel-doc:: include/uapi/linux/landlock.h
    :identifiers: landlock_rule_type landlock_path_beneath_attr
                  landlock_net_port_attr

Enforcing a ruleset
-------------------

.. kernel-doc:: security/landlock/syscalls.c
    :identifiers: sys_landlock_restrict_self

현재 제한: topology, 특수 filesystem과 계층 수

472-506

파일시스템 제한으로 sandbox된 thread는 `mount(2)`나 `pivot_root(2)`로 filesystem topology를 바꿀 수 없습니다. 그러나 `chroot(2)` 호출은 거부하지 않습니다.

일반 파일과 디렉터리는 ruleset이 처리하는 access에 따라 제한할 수 있습니다. 하지만 pipe나 socket처럼 사용자에게 보이는 filesystem에서 오지 않으면서 `/proc/<pid>/fd/*`로 접근 가능한 파일은 현재 명시적으로 제한할 수 없습니다.

`/proc/<pid>/ns/*`로 접근하는 nsfs 같은 일부 특수 kernel filesystem도 현재 명시적으로 제한할 수 없습니다.

그럼에도 ptrace 제한 덕분에 민감한 `/proc` 파일 접근은 domain hierarchy에 따라 자동 제한됩니다. 향후에는 전용 ruleset flag로 이런 경로를 명시적으로 제한할 수 있게 될 수 있습니다.

쌓을 수 있는 ruleset 계층은 16개로 제한됩니다. 16개 ruleset을 상속한 task가 보완 ruleset을 하나 더 강제하려 하면 문제가 됩니다.

한도에 도달하면 `sys_landlock_restrict_self()`가 `E2BIG`을 반환합니다.

따라서 thread 생명주기에서 ruleset을 신중하게 한 번 구성하는 것이 강하게 권장됩니다. shell이나 container manager처럼 다른 응용 프로그램을 실행하고 그 응용 프로그램도 자신을 sandbox하려는 환경에서는 특히 중요합니다.

현재 구조적 제한
항목설명
mount·pivot_rootfilesystem 제한을 받은 thread에서 topology 변경 불가
chrootLandlock이 거부하지 않음
pipe·socket FD/proc/<pid>/fd 경로에서 명시적 제한 불가
nsfs/proc/<pid>/ns 경로에서 명시적 제한 불가
보완 보호ptrace domain hierarchy 제한
최대 ruleset layer16개
한도 초과landlock_restrict_self()가 E2BIG

명시적으로 다루지 못하는 객체와 계층 한도를 정리합니다.

Current limitations
===================

Filesystem topology modification
--------------------------------

Threads sandboxed with filesystem restrictions cannot modify filesystem
topology, whether via :manpage:`mount(2)` or :manpage:`pivot_root(2)`.
However, :manpage:`chroot(2)` calls are not denied.

Special filesystems
-------------------

Access to regular files and directories can be restricted by Landlock,
according to the handled accesses of a ruleset.  However, files that do not
come from a user-visible filesystem (e.g. pipe, socket), but can still be
accessed through ``/proc/<pid>/fd/*``, cannot currently be explicitly
restricted.  Likewise, some special kernel filesystems such as nsfs, which can
be accessed through ``/proc/<pid>/ns/*``, cannot currently be explicitly
restricted.  However, thanks to the `ptrace restrictions`_, access to such
sensitive ``/proc`` files are automatically restricted according to domain
hierarchies.  Future Landlock evolutions could still enable to explicitly
restrict such paths with dedicated ruleset flags.

Ruleset layers
--------------

There is a limit of 16 layers of stacked rulesets.  This can be an issue for a
task willing to enforce a new ruleset in complement to its 16 inherited
rulesets.  Once this limit is reached, sys_landlock_restrict_self() returns
E2BIG.  It is then strongly suggested to carefully build rulesets once in the
life of a thread, especially for applications able to launch other applications
that may also want to sandbox themselves (e.g. shells, container managers,
etc.).

메모리 계상과 IOCTL 제한

507-534

ruleset 생성에 할당된 kernel memory는 계상되며 cgroup v1 memory controller로 제한할 수 있습니다.

`LANDLOCK_ACCESS_FS_IOCTL_DEV`는 `ioctl(2)` 사용을 제한하지만 새로 연 device file에만 적용됩니다. 따라서 stdin, stdout, stderr처럼 이미 존재하던 file descriptor에는 영향을 주지 않습니다.

TTY device는 전통적으로 `TIOCSTI`와 `TIOCLINUX` IOCTL command를 통해 같은 TTY의 다른 process를 제어할 수 있었습니다.

현대 Linux에서는 두 command 모두 `CAP_SYS_ADMIN`을 요구하지만 `TIOCSTI` 동작은 설정에 따라 달라질 수 있습니다.

오래된 시스템에서는 상속된 TTY file descriptor를 닫거나, 가능하다면 `LANDLOCK_ACCESS_FS_IOCTL_DEV` 권한 없이 `/proc/self/fd/*`에서 다시 여는 것이 권장됩니다.

현재 Landlock의 IOCTL 지원은 거친 단위로만 제어하지만 향후 더 세밀해질 수 있습니다.

그때까지 사용자는 정말 필요한 파일에만 `LANDLOCK_ACCESS_FS_IOCTL_DEV`를 허용하여 file hierarchy로 필요한 보증을 세워야 합니다.

IOCTL_DEV 적용 범위
항목설명
적용새로 연 character·block device file
비적용기존 stdin·stdout·stderr
TTY 위험TIOCSTI·TIOCLINUX
현대 kernel두 command에 CAP_SYS_ADMIN 필요
오래된 시스템 대응상속 TTY FD를 닫거나 제한된 상태로 재개방
정책 권장필요한 device file에만 IOCTL_DEV 허용

이미 열린 descriptor와 새로 연 device file의 차이가 핵심입니다.

Memory usage
------------

Kernel memory allocated to create rulesets is accounted and can be restricted
by the Documentation/admin-guide/cgroup-v1/memory.rst.

IOCTL support
-------------

The ``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right restricts the use of
:manpage:`ioctl(2)`, but it only applies to *newly opened* device files.  This
means specifically that pre-existing file descriptors like stdin, stdout and
stderr are unaffected.

Users should be aware that TTY devices have traditionally permitted to control
other processes on the same TTY through the ``TIOCSTI`` and ``TIOCLINUX`` IOCTL
commands.  Both of these require ``CAP_SYS_ADMIN`` on modern Linux systems, but
the behavior is configurable for ``TIOCSTI``.

On older systems, it is therefore recommended to close inherited TTY file
descriptors, or to reopen them from ``/proc/self/fd/*`` without the
``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right, if possible.

Landlock's IOCTL support is coarse-grained at the moment, but may become more
fine-grained in the future.  Until then, users are advised to establish the
guarantees that they need through the file hierarchy, by only allowing the
``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right on files where it is really required.

이전 ABI의 rename, link와 truncate 제한

535-563

Landlock은 권한 없는 접근 제어를 목표로 하므로 여러 규칙의 합성과 nesting을 올바르게 처리해야 합니다. 파일 접근을 제한하는 여러 ruleset 계층은 parent에서 그 hierarchy로 제한이 상속되는 의미도 가집니다.

파일은 hierarchy로 식별하고 제한하므로 한 디렉터리에서 다른 디렉터리로 파일을 이동하거나 link하면 hierarchy 제약을 전파하거나, 사라질 수 있는 제약에 맞추어 동작 자체를 제한해야 합니다.

권한 상승을 막고 구현을 단순하게 유지하기 위해 과거 Landlock은 같은 디렉터리 안에서만 link와 rename을 허용했습니다.

ABI version 2부터 `LANDLOCK_ACCESS_FS_REFER` access right로 rename과 linking을 안전하게 제어할 수 있습니다.

세 번째 ABI 전에는 file truncation을 거부할 수 없어서 ABI 1이나 2만 지원하는 kernel에서는 항상 허용됩니다. ABI version 3부터 `LANDLOCK_ACCESS_FS_TRUNCATE`로 truncate를 안전하게 제어할 수 있습니다.

Filesystem 기능의 ABI 도입
항목설명
ABI < 2link·rename을 같은 디렉터리로 제한
ABI >= 2LANDLOCK_ACCESS_FS_REFER
ABI < 3file truncation을 거부할 수 없음
ABI >= 3LANDLOCK_ACCESS_FS_TRUNCATE

초기 ABI의 제한과 이를 해소한 access right입니다.

Previous limitations
====================

File renaming and linking (ABI < 2)
-----------------------------------

Because Landlock targets unprivileged access controls, it needs to properly
handle composition of rules.  Such property also implies rules nesting.
Properly handling multiple layers of rulesets, each one of them able to
restrict access to files, also implies inheritance of the ruleset restrictions
from a parent to its hierarchy.  Because files are identified and restricted by
their hierarchy, moving or linking a file from one directory to another implies
propagation of the hierarchy constraints, or restriction of these actions
according to the potentially lost constraints.  To protect against privilege
escalations through renaming or linking, and for the sake of simplicity,
Landlock previously limited linking and renaming to the same directory.
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``
access right.

File truncation (ABI < 3)
-------------------------

File truncation could not be denied before the third Landlock ABI, so it is
always allowed when using a kernel that only supports the first or second ABI.

Starting with the Landlock ABI version 3, it is now possible to securely control
truncation thanks to the new ``LANDLOCK_ACCESS_FS_TRUNCATE`` access right.

ABI 4~7에서 추가된 제한

564-606

ABI version 4부터 `LANDLOCK_ACCESS_NET_BIND_TCP`와 `LANDLOCK_ACCESS_NET_CONNECT_TCP`로 TCP bind와 connect 동작을 허용된 port 집합으로 제한할 수 있습니다.

다섯 번째 ABI 전에는 IOCTL 동작을 거부할 수 없으므로 더 이른 ABI만 지원하는 kernel에서 `ioctl(2)`은 항상 허용됩니다.

ABI version 5부터 `LANDLOCK_ACCESS_FS_IOCTL_DEV`로 character device와 block device의 `ioctl(2)` 사용을 제한할 수 있습니다.

ABI version 6부터 ruleset attribute의 `scoped`에 `LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET`을 설정하여 abstract `unix(7)` socket 연결을 제한할 수 있습니다.

같은 ABI version 6부터 `LANDLOCK_SCOPE_SIGNAL`을 설정하여 `signal(7)` 전송을 제한할 수 있습니다.

ABI version 7부터 `sys_landlock_restrict_self()`에 flag를 전달하여 Landlock audit event logging을 제어할 수 있습니다.

관련 flag는 `LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF`, `LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON`, `LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF`입니다.

audit의 자세한 내용은 `Documentation/admin-guide/LSM/landlock.rst`를 참조합니다.

Landlock ABI 기능 연혁
항목설명
ABI 2REFER: rename·link
ABI 3TRUNCATE
ABI 4TCP BIND·CONNECT
ABI 5device IOCTL
ABI 6abstract UNIX socket·signal scope
ABI 7audit logging flag

각 ABI에서 처음 제어할 수 있게 된 동작입니다.

ABI 기능 확장
ABI 1 기본 filesystem 접근ABI 2 rename·linkABI 3 truncateABI 4 TCP portABI 5 device ioctlABI 6 IPC scopeABI 7 audit logging

초기 filesystem 중심 정책이 network, device, IPC, audit 제어로 확장됐습니다.

TCP bind and connect (ABI < 4)
------------------------------

Starting with the Landlock ABI version 4, it is now possible to restrict TCP
bind and connect actions to only a set of allowed ports thanks to the new
``LANDLOCK_ACCESS_NET_BIND_TCP`` and ``LANDLOCK_ACCESS_NET_CONNECT_TCP``
access rights.

Device IOCTL (ABI < 5)
----------------------

IOCTL operations could not be denied before the fifth Landlock ABI, so
:manpage:`ioctl(2)` is always allowed when using a kernel that only supports an
earlier ABI.

Starting with the Landlock ABI version 5, it is possible to restrict the use of
:manpage:`ioctl(2)` on character and block devices using the new
``LANDLOCK_ACCESS_FS_IOCTL_DEV`` right.

Abstract UNIX socket (ABI < 6)
------------------------------

Starting with the Landlock ABI version 6, it is possible to restrict
connections to an abstract :manpage:`unix(7)` socket by setting
``LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET`` to the ``scoped`` ruleset attribute.

Signal (ABI < 6)
----------------

Starting with the Landlock ABI version 6, it is possible to restrict
:manpage:`signal(7)` sending by setting ``LANDLOCK_SCOPE_SIGNAL`` to the
``scoped`` ruleset attribute.

Logging (ABI < 7)
-----------------

Starting with the Landlock ABI version 7, it is possible to control logging of
Landlock audit events with the ``LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF``,
``LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON``, and
``LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF`` flags passed to
sys_landlock_restrict_self().  See Documentation/admin-guide/LSM/landlock.rst
for more details on audit.

Kernel build 설정

607-622

Landlock은 Linux 5.13에서 처음 도입됐지만 build 시 `CONFIG_SECURITY_LANDLOCK=y`로 설정해야 합니다.

다른 보안 모듈과 마찬가지로 boot 시에도 활성화되어야 합니다. 기본 활성 보안 모듈 목록은 `CONFIG_LSM`으로 정합니다.

kernel 설정에는 `CONFIG_LSM=landlock,[...]`이 들어 있어야 하며 `[...]`는 실행 시스템에 필요한 다른 보안 모듈 목록입니다.

정확한 구성 의미는 `CONFIG_LSM` help를 참조합니다.

Build-time 요구 사항
항목설명
기능 포함CONFIG_SECURITY_LANDLOCK=y
기본 활성화CONFIG_LSM에 landlock 포함
예시CONFIG_LSM=landlock,[다른 LSM 목록]
최초 도입Linux 5.13

Landlock 코드 포함과 기본 LSM 목록을 모두 설정해야 합니다.

.. _kernel_support:

Kernel support
==============

Build time configuration
------------------------

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 like other security modules.  The list of security modules enabled by
default is set with ``CONFIG_LSM``.  The kernel configuration should then
contain ``CONFIG_LSM=landlock,[...]`` with ``[...]``  as the list of other
potentially useful security modules for the running system (see the
``CONFIG_LSM`` help).

Boot 설정과 활성화 확인

623-665

실행 중 kernel의 `CONFIG_LSM`에 `landlock`이 없다면 boot loader의 kernel command line에 `lsm=landlock,[...]`을 추가하여 활성화할 수 있습니다.

현재 built-in 설정은 `/boot/config-$(uname -r)` 또는 `/proc/config.gz`에서 `CONFIG_LSM`을 조회해 확인합니다. 원문 예시는 `lockdown,yama,integrity,apparmor`입니다.

`/proc/cmdline`에서 `lsm=` 인자를 추출해 boot command line에도 landlock이 없는지 확인합니다.

두 곳 모두에 없다면 boot loader가 기존 목록 앞에 `landlock,`을 붙여 `lsm=landlock,lockdown,yama,integrity,apparmor`를 전달하도록 설정합니다.

재부팅 뒤 `dmesg | grep landlock || journalctl -kb -g landlock`로 kernel log를 확인합니다.

정상 log에는 command line의 `lsm=landlock,...`, `LSM: initializing ... landlock ...`, 그리고 `landlock: Up and running.`이 나타납니다.

kernel build 설정이 `lockdown`과 `capability` LSM을 항상 load하도록 할 수 있습니다. 이 경우 boot loader에 명시하지 않았더라도 `LSM: initializing` log 앞부분에 이 모듈들이 표시됩니다.

Boot-time 활성화 절차
항목설명
1CONFIG_LSM 조회
2/proc/cmdline의 lsm= 조회
3boot loader 목록 앞에 landlock 추가
4재부팅
5LSM initializing과 Up and running log 확인

설정 확인부터 재부팅 후 log 검증까지의 순서입니다.

Landlock boot 활성화
CONFIG_SECURITY_LANDLOCK=y 확인CONFIG_LSM 확인현재 lsm= command line 확인lsm=landlock,... 설정재부팅kernel log에서 초기화 확인

build에 포함된 Landlock을 boot LSM 목록에 넣고 실제 초기화를 검증합니다.

Boot time configuration
-----------------------

If the running kernel does not have ``landlock`` in ``CONFIG_LSM``, then we can
enable Landlock by adding ``lsm=landlock,[...]`` to
Documentation/admin-guide/kernel-parameters.rst in the boot loader
configuration.

For example, if the current built-in configuration is:

.. code-block:: console

    $ zgrep -h "^CONFIG_LSM=" "/boot/config-$(uname -r)" /proc/config.gz 2>/dev/null
    CONFIG_LSM="lockdown,yama,integrity,apparmor"

...and if the cmdline doesn't contain ``landlock`` either:

.. code-block:: console

    $ sed -n 's/.*\(\<lsm=\S\+\).*/\1/p' /proc/cmdline
    lsm=lockdown,yama,integrity,apparmor

...we should configure the boot loader to set a cmdline extending the ``lsm``
list with the ``landlock,`` prefix::

  lsm=landlock,lockdown,yama,integrity,apparmor

After a reboot, we can check that Landlock is up and running by looking at
kernel logs:

.. code-block:: console

    # dmesg | grep landlock || journalctl -kb -g landlock
    [    0.000000] Command line: [...] lsm=landlock,lockdown,yama,integrity,apparmor
    [    0.000000] Kernel command line: [...] lsm=landlock,lockdown,yama,integrity,apparmor
    [    0.000000] LSM: initializing lsm=lockdown,capability,landlock,yama,integrity,apparmor
    [    0.000000] landlock: Up and running.

The kernel may be configured at build time to always load the ``lockdown`` and
``capability`` LSMs.  In that case, these LSMs will appear at the beginning of
the ``LSM: initializing`` log line as well, even if they are not configured in
the boot loader.

Kernel network 지원

666-674

`LANDLOCK_ACCESS_NET_BIND_TCP` 같은 network 규칙으로 TCP 동작을 명시적으로 허용하려면 kernel이 TCP를 지원해야 하며 `CONFIG_INET=y`가 필요합니다.

TCP를 지원하지 않으면 `sys_landlock_add_rule()`이 `EAFNOSUPPORT`를 반환합니다.

이 오류는 안전하게 무시할 수 있습니다. TCP 자체가 없는 kernel에서는 해당 종류의 TCP 동작이 이미 불가능하기 때문입니다.

Network rule 전제
항목설명
필수 설정CONFIG_INET=y
미지원 오류EAFNOSUPPORT
처리해당 TCP 동작 자체가 불가능하므로 안전하게 무시 가능

TCP 기능이 없을 때의 오류는 보안 저하를 뜻하지 않습니다.

Network support
---------------

To be able to explicitly allow TCP operations (e.g., adding a network rule with
``LANDLOCK_ACCESS_NET_BIND_TCP``), the kernel must support TCP
(``CONFIG_INET=y``).  Otherwise, sys_landlock_add_rule() returns an
``EAFNOSUPPORT`` error, which can safely be ignored because this kind of TCP
operation is already not possible.

질문과 답변

675-700

사용자 공간 sandbox manager가 kernel resource 제한을 대신 강제하면 race condition이나 일관되지 않은 평가가 생길 수 있습니다. 문서는 syscall interposition 기반 보안 도구가 OS code와 state를 부정확하게 mirror하는 문제를 관련 연구로 연결합니다.

Landlock은 kernel 안에서 실제 객체 접근을 판정하여 이런 사용자 공간 mirror의 구조적 한계를 피합니다.

namespace도 sandbox 구성에 도움이 되지만 access control을 위해 설계된 것은 아니므로 세밀한 제한 같은 유용한 기능이 부족합니다.

또한 namespace의 복잡성은 보안 문제를 낳을 수 있으며 신뢰할 수 없는 process가 이를 조작할 수 있을 때 특히 위험합니다. 사용자 namespace 접근 제어에 관한 LWN 자료가 함께 제시됩니다.

Landlock audit record를 비활성화하거나 줄이려면 `Documentation/admin-guide/LSM/landlock.rst`에서 설명하는 filter를 적용할 수 있습니다.

따라서 Landlock은 namespace나 사용자 공간 manager의 모든 기능을 대체하려는 것이 아니라, kernel 객체에 대한 세밀하고 쌓을 수 있는 자체 제한 계층을 제공합니다.

Landlock 관련 선택지
항목설명
사용자 공간 managerkernel state mirror에서 race·불일치 가능
Namespace격리에는 유용하지만 세밀한 access control 목적은 아님
Landlockkernel 객체 접근에 추가 제한을 직접 강제
Audit 조정admin-guide/LSM/landlock.rst의 filter 사용

다른 sandbox 기법의 역할과 주의점을 비교합니다.

Questions and answers
=====================

What about user space sandbox managers?
---------------------------------------

Using user space processes to enforce restrictions on kernel resources can lead
to race conditions or inconsistent evaluations (i.e. `Incorrect mirroring of
the OS code and state
<https://www.ndss-symposium.org/ndss2003/traps-and-pitfalls-practical-problems-system-call-interposition-based-security-tools/>`_).

What about namespaces and containers?
-------------------------------------

Namespaces can help create sandboxes but they are not designed for
access-control and then miss useful features for such use case (e.g. no
fine-grained restrictions).  Moreover, their complexity can lead to security
issues, especially when untrusted processes can manipulate them (cf.
`Controlling access to user namespaces <https://lwn.net/Articles/673597/>`_).

How to disable Landlock audit records?
--------------------------------------

You might want to put in place filters as explained here:
Documentation/admin-guide/LSM/landlock.rst

추가 문서와 예제

701-710

관리자용 system-wide Landlock와 audit 문서는 `Documentation/admin-guide/LSM/landlock.rst`에 있습니다.

Landlock LSM 내부 설계 문서는 `Documentation/security/landlock.rst`에 있고 프로젝트 사이트는 `https://landlock.io`입니다.

완전한 sandbox 예제 `samples/landlock/sandboxer.c`는 stable Linux 저장소의 해당 source 경로로 연결됩니다.

추가 자료
항목설명
관리·auditDocumentation/admin-guide/LSM/landlock.rst
LSM 설계Documentation/security/landlock.rst
프로젝트https://landlock.io
동작 예제samples/landlock/sandboxer.c

사용자 API를 넘어 운영·내부 설계·실제 코드를 확인할 수 있습니다.

Additional documentation
========================

* Documentation/admin-guide/LSM/landlock.rst
* Documentation/security/landlock.rst
* https://landlock.io

.. Links
.. _samples/landlock/sandboxer.c:
   https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/samples/landlock/sandboxer.c