Landlock-Sharp

Deny logging

Landlock can audit accesses it blocks. Kernel 6.13 (Landlock ABI 7) added three flags on landlock_restrict_self that control how denials are recorded — useful when you're tuning a ruleset or diagnosing a permission issue in production.

The C# binding exposes the flags as optional parameters on Enforce(). On older kernels they're silently ignored. See landlock_restrict_self(2) for the kernel-side definition.


The three flags

sandbox.Enforce(
    disableDenyLogging:           false,
    enableChildDenyLogging:       false,
    disabledNestedDomainsLogging: false);
Parameter Kernel constant Default Effect
disableDenyLogging LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF false (logging on) Stops the kernel from logging denials caused by this domain in the current execution. Use when the ruleset is working as intended and the noise is hurting log signal.
enableChildDenyLogging LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON false (off) Turns logging on for denials in child processes that come from a new execve (e.g. a forked-and-exec'd worker). Off by default to avoid log spam from short-lived child tools.
disabledNestedDomainsLogging LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF false (logging on) Stops logging for denials caused by layered domains that are nested inside the current one.

If none of the flags are set, the kernel uses its default policy — log denials caused by the current domain in the current exec, log denials in nested subdomains, but don't log denials caused after a child execve.


Reading the audit log

Landlock denials are emitted as kernel audit records. The easiest way to read them is journalctl on systemd hosts:

journalctl -k --since "5 min ago" | grep -i landlock
# or
ausearch -m AVC,SECCOMP --start recent | grep landlock

A typical record looks like:

audit: type=1400 audit(...) landlock: domain=42 access=read_file pid=12345 \
       comm="MyApp" path="/etc/shadow"

For the full audit-record format see landlock(7) — "Audit log".

Why "deny logging" and not "audit all"?

Landlock only logs denials. Successful, allowed accesses are never logged — by design, because the volume would be enormous. If you want full-audit semantics, layer Landlock with auditd filters.


When to use each flag

  • Default (all parameters false). The right answer for almost everyone. The kernel logs the denials that are most actionable and skips the noisy categories.

  • disableDenyLogging = true — once a ruleset is tuned and the denials in production are expected (e.g. a probe checking for files it shouldn't have), turning logging off for the main domain reduces audit volume.

  • enableChildDenyLogging = true — when you sandbox a parent process that spawns workers via execve and you want denials inside the workers to be auditable. Useful for plugin hosts.

  • disabledNestedDomainsLogging = true — when you intentionally layer multiple Landlock domains (see Enforcing the sandbox) and only want the outermost domain's denials in the log.


Cross-reference

© 2026 Landlock-Sharp. All rights reserved.