Skip to content

Commit 7288511

Browse files
committed
Merge tag 'landlock-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux
Pull landlock updates from Mickaël Salaün: "This brings two main changes to Landlock: - A signal scoping fix with a new interface for user space to know if it is compatible with the running kernel. - Audit support to give visibility on why access requests are denied, including the origin of the security policy, missing access rights, and description of object(s). This was designed to limit log spam as much as possible while still alerting about unexpected blocked access. With these changes come new and improved documentation, and a lot of new tests" * tag 'landlock-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux: (36 commits) landlock: Add audit documentation selftests/landlock: Add audit tests for network selftests/landlock: Add audit tests for filesystem selftests/landlock: Add audit tests for abstract UNIX socket scoping selftests/landlock: Add audit tests for ptrace selftests/landlock: Test audit with restrict flags selftests/landlock: Add tests for audit flags and domain IDs selftests/landlock: Extend tests for landlock_restrict_self(2)'s flags selftests/landlock: Add test for invalid ruleset file descriptor samples/landlock: Enable users to log sandbox denials landlock: Add LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF landlock: Add LANDLOCK_RESTRICT_SELF_LOG_*_EXEC_* flags landlock: Log scoped denials landlock: Log TCP bind and connect denials landlock: Log truncate and IOCTL denials landlock: Factor out IOCTL hooks landlock: Log file-related denials landlock: Log mount-related denials landlock: Add AUDIT_LANDLOCK_DOMAIN and log domain status landlock: Add AUDIT_LANDLOCK_ACCESS and log ptrace denials ...
2 parents 78fb88e + 8e2dd47 commit 7288511

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+4960
-315
lines changed

Documentation/admin-guide/LSM/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,4 @@ subdirectories.
4848
Yama
4949
SafeSetID
5050
ipe
51+
landlock
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
.. Copyright © 2025 Microsoft Corporation
3+
4+
================================
5+
Landlock: system-wide management
6+
================================
7+
8+
:Author: Mickaël Salaün
9+
:Date: March 2025
10+
11+
Landlock can leverage the audit framework to log events.
12+
13+
User space documentation can be found here:
14+
Documentation/userspace-api/landlock.rst.
15+
16+
Audit
17+
=====
18+
19+
Denied access requests are logged by default for a sandboxed program if `audit`
20+
is enabled. This default behavior can be changed with the
21+
sys_landlock_restrict_self() flags (cf.
22+
Documentation/userspace-api/landlock.rst). Landlock logs can also be masked
23+
thanks to audit rules. Landlock can generate 2 audit record types.
24+
25+
Record types
26+
------------
27+
28+
AUDIT_LANDLOCK_ACCESS
29+
This record type identifies a denied access request to a kernel resource.
30+
The ``domain`` field indicates the ID of the domain that blocked the
31+
request. The ``blockers`` field indicates the cause(s) of this denial
32+
(separated by a comma), and the following fields identify the kernel object
33+
(similar to SELinux). There may be more than one of this record type per
34+
audit event.
35+
36+
Example with a file link request generating two records in the same event::
37+
38+
domain=195ba459b blockers=fs.refer path="/usr/bin" dev="vda2" ino=351
39+
domain=195ba459b blockers=fs.make_reg,fs.refer path="/usr/local" dev="vda2" ino=365
40+
41+
AUDIT_LANDLOCK_DOMAIN
42+
This record type describes the status of a Landlock domain. The ``status``
43+
field can be either ``allocated`` or ``deallocated``.
44+
45+
The ``allocated`` status is part of the same audit event and follows
46+
the first logged ``AUDIT_LANDLOCK_ACCESS`` record of a domain. It identifies
47+
Landlock domain information at the time of the sys_landlock_restrict_self()
48+
call with the following fields:
49+
50+
- the ``domain`` ID
51+
- the enforcement ``mode``
52+
- the domain creator's ``pid``
53+
- the domain creator's ``uid``
54+
- the domain creator's executable path (``exe``)
55+
- the domain creator's command line (``comm``)
56+
57+
Example::
58+
59+
domain=195ba459b status=allocated mode=enforcing pid=300 uid=0 exe="/root/sandboxer" comm="sandboxer"
60+
61+
The ``deallocated`` status is an event on its own and it identifies a
62+
Landlock domain release. After such event, it is guarantee that the
63+
related domain ID will never be reused during the lifetime of the system.
64+
The ``domain`` field indicates the ID of the domain which is released, and
65+
the ``denials`` field indicates the total number of denied access request,
66+
which might not have been logged according to the audit rules and
67+
sys_landlock_restrict_self()'s flags.
68+
69+
Example::
70+
71+
domain=195ba459b status=deallocated denials=3
72+
73+
74+
Event samples
75+
--------------
76+
77+
Here are two examples of log events (see serial numbers).
78+
79+
In this example a sandboxed program (``kill``) tries to send a signal to the
80+
init process, which is denied because of the signal scoping restriction
81+
(``LL_SCOPED=s``)::
82+
83+
$ LL_FS_RO=/ LL_FS_RW=/ LL_SCOPED=s LL_FORCE_LOG=1 ./sandboxer kill 1
84+
85+
This command generates two events, each identified with a unique serial
86+
number following a timestamp (``msg=audit(1729738800.268:30)``). The first
87+
event (serial ``30``) contains 4 records. The first record
88+
(``type=LANDLOCK_ACCESS``) shows an access denied by the domain `1a6fdc66f`.
89+
The cause of this denial is signal scopping restriction
90+
(``blockers=scope.signal``). The process that would have receive this signal
91+
is the init process (``opid=1 ocomm="systemd"``).
92+
93+
The second record (``type=LANDLOCK_DOMAIN``) describes (``status=allocated``)
94+
domain `1a6fdc66f`. This domain was created by process ``286`` executing the
95+
``/root/sandboxer`` program launched by the root user.
96+
97+
The third record (``type=SYSCALL``) describes the syscall, its provided
98+
arguments, its result (``success=no exit=-1``), and the process that called it.
99+
100+
The fourth record (``type=PROCTITLE``) shows the command's name as an
101+
hexadecimal value. This can be translated with ``python -c
102+
'print(bytes.fromhex("6B696C6C0031"))'``.
103+
104+
Finally, the last record (``type=LANDLOCK_DOMAIN``) is also the only one from
105+
the second event (serial ``31``). It is not tied to a direct user space action
106+
but an asynchronous one to free resources tied to a Landlock domain
107+
(``status=deallocated``). This can be useful to know that the following logs
108+
will not concern the domain ``1a6fdc66f`` anymore. This record also summarize
109+
the number of requests this domain denied (``denials=1``), whether they were
110+
logged or not.
111+
112+
.. code-block::
113+
114+
type=LANDLOCK_ACCESS msg=audit(1729738800.268:30): domain=1a6fdc66f blockers=scope.signal opid=1 ocomm="systemd"
115+
type=LANDLOCK_DOMAIN msg=audit(1729738800.268:30): domain=1a6fdc66f status=allocated mode=enforcing pid=286 uid=0 exe="/root/sandboxer" comm="sandboxer"
116+
type=SYSCALL msg=audit(1729738800.268:30): arch=c000003e syscall=62 success=no exit=-1 [..] ppid=272 pid=286 auid=0 uid=0 gid=0 [...] comm="kill" [...]
117+
type=PROCTITLE msg=audit(1729738800.268:30): proctitle=6B696C6C0031
118+
type=LANDLOCK_DOMAIN msg=audit(1729738800.324:31): domain=1a6fdc66f status=deallocated denials=1
119+
120+
Here is another example showcasing filesystem access control::
121+
122+
$ LL_FS_RO=/ LL_FS_RW=/tmp LL_FORCE_LOG=1 ./sandboxer sh -c "echo > /etc/passwd"
123+
124+
The related audit logs contains 8 records from 3 different events (serials 33,
125+
34 and 35) created by the same domain `1a6fdc679`::
126+
127+
type=LANDLOCK_ACCESS msg=audit(1729738800.221:33): domain=1a6fdc679 blockers=fs.write_file path="/dev/tty" dev="devtmpfs" ino=9
128+
type=LANDLOCK_DOMAIN msg=audit(1729738800.221:33): domain=1a6fdc679 status=allocated mode=enforcing pid=289 uid=0 exe="/root/sandboxer" comm="sandboxer"
129+
type=SYSCALL msg=audit(1729738800.221:33): arch=c000003e syscall=257 success=no exit=-13 [...] ppid=272 pid=289 auid=0 uid=0 gid=0 [...] comm="sh" [...]
130+
type=PROCTITLE msg=audit(1729738800.221:33): proctitle=7368002D63006563686F203E202F6574632F706173737764
131+
type=LANDLOCK_ACCESS msg=audit(1729738800.221:34): domain=1a6fdc679 blockers=fs.write_file path="/etc/passwd" dev="vda2" ino=143821
132+
type=SYSCALL msg=audit(1729738800.221:34): arch=c000003e syscall=257 success=no exit=-13 [...] ppid=272 pid=289 auid=0 uid=0 gid=0 [...] comm="sh" [...]
133+
type=PROCTITLE msg=audit(1729738800.221:34): proctitle=7368002D63006563686F203E202F6574632F706173737764
134+
type=LANDLOCK_DOMAIN msg=audit(1729738800.261:35): domain=1a6fdc679 status=deallocated denials=2
135+
136+
137+
Event filtering
138+
---------------
139+
140+
If you get spammed with audit logs related to Landlock, this is either an
141+
attack attempt or a bug in the security policy. We can put in place some
142+
filters to limit noise with two complementary ways:
143+
144+
- with sys_landlock_restrict_self()'s flags if we can fix the sandboxed
145+
programs,
146+
- or with audit rules (see :manpage:`auditctl(8)`).
147+
148+
Additional documentation
149+
========================
150+
151+
* `Linux Audit Documentation`_
152+
* Documentation/userspace-api/landlock.rst
153+
* Documentation/security/landlock.rst
154+
* https://landlock.io
155+
156+
.. Links
157+
.. _Linux Audit Documentation:
158+
https://github.com/linux-audit/audit-documentation/wiki

Documentation/security/landlock.rst

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Landlock LSM: kernel documentation
77
==================================
88

99
:Author: Mickaël Salaün
10-
:Date: December 2022
10+
:Date: March 2025
1111

1212
Landlock's goal is to create scoped access-control (i.e. sandboxing). To
1313
harden a whole system, this feature should be available to any process,
@@ -45,6 +45,10 @@ Guiding principles for safe access controls
4545
sandboxed process shall retain their scoped accesses (at the time of resource
4646
acquisition) whatever process uses them.
4747
Cf. `File descriptor access rights`_.
48+
* Access denials shall be logged according to system and Landlock domain
49+
configurations. Log entries must contain information about the cause of the
50+
denial and the owner of the related security policy. Such log generation
51+
should have a negligible performance and memory impact on allowed requests.
4852

4953
Design choices
5054
==============
@@ -124,6 +128,13 @@ makes the reasoning much easier and helps avoid pitfalls.
124128
.. kernel-doc:: security/landlock/ruleset.h
125129
:identifiers:
126130

131+
Additional documentation
132+
========================
133+
134+
* Documentation/userspace-api/landlock.rst
135+
* Documentation/admin-guide/LSM/landlock.rst
136+
* https://landlock.io
137+
127138
.. Links
128139
.. _tools/testing/selftests/landlock/:
129140
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/tools/testing/selftests/landlock/

Documentation/userspace-api/landlock.rst

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Landlock: unprivileged access control
88
=====================================
99

1010
:Author: Mickaël Salaün
11-
:Date: January 2025
11+
:Date: March 2025
1212

1313
The goal of Landlock is to enable restriction of ambient rights (e.g. global
1414
filesystem or network access) for a set of processes. Because Landlock
@@ -317,33 +317,32 @@ IPC scoping
317317
-----------
318318

319319
Similar to the implicit `Ptrace restrictions`_, we may want to further restrict
320-
interactions between sandboxes. Each Landlock domain can be explicitly scoped
321-
for a set of actions by specifying it on a ruleset. For example, if a
322-
sandboxed process should not be able to :manpage:`connect(2)` to a
323-
non-sandboxed process through abstract :manpage:`unix(7)` sockets, we can
324-
specify such a restriction with ``LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET``.
325-
Moreover, if a sandboxed process should not be able to send a signal to a
326-
non-sandboxed process, we can specify this restriction with
327-
``LANDLOCK_SCOPE_SIGNAL``.
328-
329-
A sandboxed process can connect to a non-sandboxed process when its domain is
330-
not scoped. If a process's domain is scoped, it can only connect to sockets
331-
created by processes in the same scope.
332-
Moreover, if a process is scoped to send signal to a non-scoped process, it can
333-
only send signals to processes in the same scope.
334-
335-
A connected datagram socket behaves like a stream socket when its domain is
336-
scoped, meaning if the domain is scoped after the socket is connected, it can
337-
still :manpage:`send(2)` data just like a stream socket. However, in the same
338-
scenario, a non-connected datagram socket cannot send data (with
339-
:manpage:`sendto(2)`) outside its scope.
340-
341-
A process with a scoped domain can inherit a socket created by a non-scoped
342-
process. The process cannot connect to this socket since it has a scoped
343-
domain.
344-
345-
IPC scoping does not support exceptions, so if a domain is scoped, no rules can
346-
be added to allow access to resources or processes outside of the scope.
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.
347346

348347
Truncating files
349348
----------------
@@ -595,6 +594,16 @@ Starting with the Landlock ABI version 6, it is possible to restrict
595594
:manpage:`signal(7)` sending by setting ``LANDLOCK_SCOPE_SIGNAL`` to the
596595
``scoped`` ruleset attribute.
597596

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+
598607
.. _kernel_support:
599608

600609
Kernel support
@@ -683,9 +692,16 @@ fine-grained restrictions). Moreover, their complexity can lead to security
683692
issues, especially when untrusted processes can manipulate them (cf.
684693
`Controlling access to user namespaces <https://lwn.net/Articles/673597/>`_).
685694

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+
686701
Additional documentation
687702
========================
688703

704+
* Documentation/admin-guide/LSM/landlock.rst
689705
* Documentation/security/landlock.rst
690706
* https://landlock.io
691707

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13157,6 +13157,7 @@ L: linux-security-module@vger.kernel.org
1315713157
S: Supported
1315813158
W: https://landlock.io
1315913159
T: git https://git.kernel.org/pub/scm/linux/kernel/git/mic/linux.git
13160+
F: Documentation/admin-guide/LSM/landlock.rst
1316013161
F: Documentation/security/landlock.rst
1316113162
F: Documentation/userspace-api/landlock.rst
1316213163
F: fs/ioctl.c

include/linux/lsm_audit.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ void common_lsm_audit(struct common_audit_data *a,
132132
void (*pre_audit)(struct audit_buffer *, void *),
133133
void (*post_audit)(struct audit_buffer *, void *));
134134

135+
void audit_log_lsm_data(struct audit_buffer *ab,
136+
const struct common_audit_data *a);
137+
135138
#else /* CONFIG_AUDIT */
136139

137140
static inline void common_lsm_audit(struct common_audit_data *a,
@@ -140,6 +143,11 @@ static inline void common_lsm_audit(struct common_audit_data *a,
140143
{
141144
}
142145

146+
static inline void audit_log_lsm_data(struct audit_buffer *ab,
147+
const struct common_audit_data *a)
148+
{
149+
}
150+
143151
#endif /* CONFIG_AUDIT */
144152

145153
#endif

include/uapi/linux/audit.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
* 1100 - 1199 user space trusted application messages
3434
* 1200 - 1299 messages internal to the audit daemon
3535
* 1300 - 1399 audit event messages
36-
* 1400 - 1499 SE Linux use
36+
* 1400 - 1499 access control messages
3737
* 1500 - 1599 kernel LSPP events
3838
* 1600 - 1699 kernel crypto events
3939
* 1700 - 1799 kernel anomaly records
@@ -146,6 +146,8 @@
146146
#define AUDIT_IPE_ACCESS 1420 /* IPE denial or grant */
147147
#define AUDIT_IPE_CONFIG_CHANGE 1421 /* IPE config change */
148148
#define AUDIT_IPE_POLICY_LOAD 1422 /* IPE policy load */
149+
#define AUDIT_LANDLOCK_ACCESS 1423 /* Landlock denial */
150+
#define AUDIT_LANDLOCK_DOMAIN 1424 /* Landlock domain status */
149151

150152
#define AUDIT_FIRST_KERN_ANOM_MSG 1700
151153
#define AUDIT_LAST_KERN_ANOM_MSG 1799

0 commit comments

Comments
 (0)