1.. SPDX-License-Identifier: GPL-2.0 2.. Copyright © 2025 Microsoft Corporation 3.. Copyright © 2026 Cloudflare, Inc. 4 5================================ 6Landlock: system-wide management 7================================ 8 9:Author: Mickaël Salaün 10:Date: August 2026 11 12Landlock can leverage the audit framework to log events. 13 14User space documentation can be found here: 15Documentation/userspace-api/landlock.rst. 16 17Audit 18===== 19 20Denied access requests are logged by default for a sandboxed program if `audit` 21is enabled. This default behavior can be changed with the 22sys_landlock_restrict_self() flags (cf. 23Documentation/userspace-api/landlock.rst), or suppressed on a per-object 24basis by using ``LANDLOCK_ADD_RULE_QUIET`` (ABI 10+). Landlock logs can 25also be masked thanks to audit rules. Landlock can generate 2 audit 26record types. 27 28Record types 29------------ 30 31AUDIT_LANDLOCK_ACCESS 32 This record type identifies a denied access request to a kernel resource. 33 The ``domain`` field indicates the ID of the domain that blocked the 34 request. The ``blockers`` field indicates the cause(s) of this denial 35 (separated by a comma), and the following fields identify the kernel object 36 (similar to SELinux). There may be more than one of this record type per 37 audit event. 38 39 Example with a file link request generating two records in the same event:: 40 41 domain=195ba459b blockers=fs.refer path="/usr/bin" dev="vda2" ino=351 42 domain=195ba459b blockers=fs.make_reg,fs.refer path="/usr/local" dev="vda2" ino=365 43 44 45 The ``blockers`` field uses dot-separated prefixes to indicate the type of 46 restriction that caused the denial: 47 48 **fs.*** - Filesystem access rights (ABI 1+): 49 - fs.execute, fs.write_file, fs.read_file, fs.read_dir 50 - fs.remove_dir, fs.remove_file 51 - fs.make_char, fs.make_dir, fs.make_reg, fs.make_sock 52 - fs.make_fifo, fs.make_block, fs.make_sym 53 - fs.refer (ABI 2+) 54 - fs.truncate (ABI 3+) 55 - fs.ioctl_dev (ABI 5+) 56 - fs.resolve_unix (ABI 9+) 57 58 **net.*** - Network access rights (ABI 4+): 59 - net.bind_tcp - TCP port binding was denied 60 - net.connect_tcp - TCP connection was denied 61 - net.bind_udp - UDP port binding was denied 62 - net.connect_send_udp - UDP connection and send was denied 63 64 **scope.*** - IPC scoping restrictions (ABI 6+): 65 - scope.abstract_unix_socket - Abstract UNIX socket connection denied 66 - scope.signal - Signal sending denied 67 68 Multiple blockers can appear in a single event (comma-separated) when 69 multiple access rights are missing. For example, creating a regular file 70 in a directory that lacks both ``make_reg`` and ``refer`` rights would show 71 ``blockers=fs.make_reg,fs.refer``. 72 73 The object identification fields (path, dev, ino for filesystem; opid, 74 ocomm for signals) depend on the type of access being blocked and provide 75 context about what resource was involved in the denial. 76 77 78AUDIT_LANDLOCK_DOMAIN 79 This record type describes the status of a Landlock domain. The ``status`` 80 field can be either ``allocated`` or ``deallocated``. 81 82 The ``allocated`` status is part of the same audit event and follows 83 the first logged ``AUDIT_LANDLOCK_ACCESS`` record of a domain. It identifies 84 Landlock domain information at the time of the sys_landlock_restrict_self() 85 call with the following fields: 86 87 - the ``domain`` ID 88 - the enforcement ``mode`` 89 - the domain creator's ``pid`` 90 - the domain creator's ``uid`` 91 - the domain creator's executable path (``exe``) 92 - the domain creator's command line (``comm``) 93 94 Example:: 95 96 domain=195ba459b status=allocated mode=enforcing pid=300 uid=0 exe="/root/sandboxer" comm="sandboxer" 97 98 The ``deallocated`` status is an event on its own and it identifies a 99 Landlock domain release. After such event, it is guarantee that the 100 related domain ID will never be reused during the lifetime of the system. 101 The ``domain`` field indicates the ID of the domain which is released, and 102 the ``denials`` field indicates the total number of denied access request, 103 which might not have been logged according to the audit rules and 104 sys_landlock_restrict_self()'s flags. 105 106 Example:: 107 108 domain=195ba459b status=deallocated denials=3 109 110 111Event samples 112-------------- 113 114Here are two examples of log events (see serial numbers). 115 116In this example a sandboxed program (``kill``) tries to send a signal to the 117init process, which is denied because of the signal scoping restriction 118(``LL_SCOPED=s``):: 119 120 $ LL_FS_RO=/ LL_FS_RW=/ LL_SCOPED=s LL_FORCE_LOG=1 ./sandboxer kill 1 121 122This command generates two events, each identified with a unique serial 123number following a timestamp (``msg=audit(1729738800.268:30)``). The first 124event (serial ``30``) contains 4 records. The first record 125(``type=LANDLOCK_ACCESS``) shows an access denied by the domain `1a6fdc66f`. 126The cause of this denial is signal scoping restriction 127(``blockers=scope.signal``). The process that would have receive this signal 128is the init process (``opid=1 ocomm="systemd"``). 129 130The second record (``type=LANDLOCK_DOMAIN``) describes (``status=allocated``) 131domain `1a6fdc66f`. This domain was created by process ``286`` executing the 132``/root/sandboxer`` program launched by the root user. 133 134The third record (``type=SYSCALL``) describes the syscall, its provided 135arguments, its result (``success=no exit=-1``), and the process that called it. 136 137The fourth record (``type=PROCTITLE``) shows the command's name as an 138hexadecimal value. This can be translated with ``python -c 139'print(bytes.fromhex("6B696C6C0031"))'``. 140 141Finally, the last record (``type=LANDLOCK_DOMAIN``) is also the only one from 142the second event (serial ``31``). It is not tied to a direct user space action 143but an asynchronous one to free resources tied to a Landlock domain 144(``status=deallocated``). This can be useful to know that the following logs 145will not concern the domain ``1a6fdc66f`` anymore. This record also summarize 146the number of requests this domain denied (``denials=1``), whether they were 147logged or not. 148 149.. code-block:: 150 151 type=LANDLOCK_ACCESS msg=audit(1729738800.268:30): domain=1a6fdc66f blockers=scope.signal opid=1 ocomm="systemd" 152 type=LANDLOCK_DOMAIN msg=audit(1729738800.268:30): domain=1a6fdc66f status=allocated mode=enforcing pid=286 uid=0 exe="/root/sandboxer" comm="sandboxer" 153 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" [...] 154 type=PROCTITLE msg=audit(1729738800.268:30): proctitle=6B696C6C0031 155 type=LANDLOCK_DOMAIN msg=audit(1729738800.324:31): domain=1a6fdc66f status=deallocated denials=1 156 157Here is another example showcasing filesystem access control:: 158 159 $ LL_FS_RO=/ LL_FS_RW=/tmp LL_FORCE_LOG=1 ./sandboxer sh -c "echo > /etc/passwd" 160 161The related audit logs contains 8 records from 3 different events (serials 33, 16234 and 35) created by the same domain `1a6fdc679`:: 163 164 type=LANDLOCK_ACCESS msg=audit(1729738800.221:33): domain=1a6fdc679 blockers=fs.write_file path="/dev/tty" dev="devtmpfs" ino=9 165 type=LANDLOCK_DOMAIN msg=audit(1729738800.221:33): domain=1a6fdc679 status=allocated mode=enforcing pid=289 uid=0 exe="/root/sandboxer" comm="sandboxer" 166 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" [...] 167 type=PROCTITLE msg=audit(1729738800.221:33): proctitle=7368002D63006563686F203E202F6574632F706173737764 168 type=LANDLOCK_ACCESS msg=audit(1729738800.221:34): domain=1a6fdc679 blockers=fs.write_file path="/etc/passwd" dev="vda2" ino=143821 169 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" [...] 170 type=PROCTITLE msg=audit(1729738800.221:34): proctitle=7368002D63006563686F203E202F6574632F706173737764 171 type=LANDLOCK_DOMAIN msg=audit(1729738800.261:35): domain=1a6fdc679 status=deallocated denials=2 172 173 174Event filtering 175--------------- 176 177If you get spammed with audit logs related to Landlock, this is either an 178attack attempt or a bug in the security policy. We can put in place some 179filters to limit noise with two complementary ways: 180 181- with sys_landlock_restrict_self()'s flags, or 182 ``LANDLOCK_ADD_RULE_QUIET`` (ABI 10+) if we can fix the sandboxed 183 programs, 184- or with audit rules (see :manpage:`auditctl(8)`). 185 186Tracepoints 187=========== 188 189Landlock also provides tracepoints as an alternative to audit for 190debugging and observability. Tracepoints fire unconditionally, 191independent of audit configuration, ``audit_enabled``, and domain log 192flags. This makes them suitable for always-on monitoring with eBPF or 193for ad-hoc debugging with ``trace-pipe``. 194 195See Documentation/trace/events-landlock.rst for the complete event 196reference: the full event list, how to enable events and read their 197output, the field formats, the ``check_rule`` interpretation guide, 198worked event samples, ftrace filtering, and eBPF access. 199 200.. _landlock_observability: 201 202When to use tracing vs audit 203----------------------------- 204 205Audit and tracing both help diagnose Landlock policy issues: 206 207**Audit** records denied accesses with the blockers, domain, and object 208identification (path, port). Audit is the standard Linux mechanism for 209security events, with a stable record format that is well established 210and already supported by log management systems, SIEM platforms, and EDR 211solutions. Audit is always active when the kernel is built with audit 212support, filtered by the Landlock log flags to reduce noise in 213production, and designed for long-term security monitoring and 214compliance. 215 216**Tracing** provides deeper introspection for policy debugging. In 217addition to denied accesses, trace events cover the complete lifecycle 218of Landlock objects (rulesets, domains) and intermediate rule matching 219during access checks. Trace events are disabled by default (zero 220overhead) and fire unconditionally. eBPF 221programs attached to trace events can access the full kernel context 222(ruleset rules, domain hierarchy, process credentials) via BTF, enabling 223richer analysis than the flat fields in audit records. For example, an 224eBPF-based live monitoring tool can correlate creation, rule-addition, 225and denial events to build a real-time view of all active Landlock 226domains and their policies. However, BTF-based access depends on 227internal kernel struct layouts which have no stability guarantee. CO-RE 228(Compile Once, Run Everywhere) provides best-effort field relocation. 229The ftrace printk format is also not a stable ABI, but is 230self-describing via the per-event ``format`` file, allowing tools to 231adapt dynamically. 232 233Observability guarantees and limitations 234----------------------------------------- 235 236Both audit records and trace events are emitted for every denied access, 237with these exceptions: 238 239- **Landlock log flags** (audit only): ``LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF``, 240 ``LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON``, and 241 ``LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF`` control which denials 242 generate audit records. Trace events fire regardless of these flags. 243 244- **NOAUDIT hooks**: Some LSM hooks suppress logging for speculative 245 permission probes (e.g., reading ``/proc/<pid>/status`` uses 246 ``PTRACE_MODE_NOAUDIT``). When NOAUDIT is set, neither audit records 247 nor trace events are emitted, and the denial is not counted in 248 ``denials``. The denial is still enforced. This avoids performance 249 overhead and noise from speculative probes that test permissions 250 without performing an actual access. 251 252- **Audit rate limiting**: The audit subsystem may silently drop records 253 when the audit queue is full. Trace events are not rate-limited. 254 255- **Tracepoint disabled**: When a trace event is disabled (the default 256 state), the tracepoint is a no-op with zero overhead. 257 258When both audit and tracing are active, every denial emits a trace event, 259and a denial that the domain's log policy selects additionally produces an 260audit record (subject to the Landlock log flags). The ``denials`` count in 261``free_domain`` events is incremented for every denial regardless of the 262log flags, so it can exceed the number of audit records (which the log 263flags and audit-side rate-limiting or exclude rules may suppress). 264 265.. _landlock_observability_security: 266 267Observability security considerations 268--------------------------------------- 269 270Both audit records and trace events expose information about all 271Landlock-sandboxed processes on the system, including filesystem paths 272being accessed, network ports, and process identities. System 273administrators must ensure that access to audit logs (controlled by the 274audit subsystem configuration) and to trace events (requiring 275``CAP_SYS_ADMIN`` or ``CAP_BPF`` + ``CAP_PERFMON``) is restricted to 276trusted users. 277 278eBPF programs attached to Landlock trace events have access to the full 279kernel context of each event (ruleset rules, domain hierarchy, process 280credentials) via BTF, exposing sensitive state about every sandboxed 281process. Restrict this access to trusted users, as for the audit logs. 282 283Audit logs and kernel trace events require elevated privileges and are 284system-wide; they are not designed for per-sandbox unprivileged 285monitoring. 286 287Additional documentation 288======================== 289 290* `Linux Audit Documentation`_ 291* Documentation/userspace-api/landlock.rst 292* Documentation/trace/events-landlock.rst 293* Documentation/security/landlock.rst 294* https://landlock.io 295 296.. Links 297.. _Linux Audit Documentation: 298 https://github.com/linux-audit/audit-documentation/wiki 299