Commit c22e26bd authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull landlock updates from Mickaël Salaün:

 - extend Landlock to enforce restrictions on a whole process, similarly
   to the seccomp's TSYNC flag

 - refactor data structures to simplify code and improve performance

 - add documentation to cover missing parts

* tag 'landlock-7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux:
  mailmap: Add entry for Mickaël Salaün
  landlock: Transpose the layer masks data structure
  landlock: Add access_mask_subset() helper
  selftests/landlock: Add filesystem access benchmark
  landlock: Document audit blocker field format
  landlock: Add errata documentation section
  landlock: Add backwards compatibility for restrict flags
  landlock: Refactor TCP socket type check
  landlock: Minor reword of docs for TCP access rights
  landlock: Document LANDLOCK_RESTRICT_SELF_TSYNC
  selftests/landlock: Add LANDLOCK_RESTRICT_SELF_TSYNC tests
  landlock: Multithreading support for landlock_restrict_self()
parents d0e91e40 e265b330
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -563,6 +563,7 @@ Michel Dänzer <michel@tungstengraphics.com>
Michel Lespinasse <michel@lespinasse.org>
Michel Lespinasse <michel@lespinasse.org> <walken@google.com>
Michel Lespinasse <michel@lespinasse.org> <walken@zoy.org>
Mickaël Salaün <mic@digikod.net> <mic@linux.microsoft.com>
Miguel Ojeda <ojeda@kernel.org> <miguel.ojeda.sandonis@gmail.com>
Mike Rapoport <rppt@kernel.org> <mike@compulab.co.il>
Mike Rapoport <rppt@kernel.org> <mike.rapoport@gmail.com>
+33 −2
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@ Landlock: system-wide management
================================

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

Landlock can leverage the audit framework to log events.

@@ -38,6 +38,37 @@ AUDIT_LANDLOCK_ACCESS
        domain=195ba459b blockers=fs.refer path="/usr/bin" dev="vda2" ino=351
        domain=195ba459b blockers=fs.make_reg,fs.refer path="/usr/local" dev="vda2" ino=365


    The ``blockers`` field uses dot-separated prefixes to indicate the type of
    restriction that caused the denial:

    **fs.*** - Filesystem access rights (ABI 1+):
        - fs.execute, fs.write_file, fs.read_file, fs.read_dir
        - fs.remove_dir, fs.remove_file
        - fs.make_char, fs.make_dir, fs.make_reg, fs.make_sock
        - fs.make_fifo, fs.make_block, fs.make_sym
        - fs.refer (ABI 2+)
        - fs.truncate (ABI 3+)
        - fs.ioctl_dev (ABI 5+)

    **net.*** - Network access rights (ABI 4+):
        - net.bind_tcp - TCP port binding was denied
        - net.connect_tcp - TCP connection was denied

    **scope.*** - IPC scoping restrictions (ABI 6+):
        - scope.abstract_unix_socket - Abstract UNIX socket connection denied
        - scope.signal - Signal sending denied

    Multiple blockers can appear in a single event (comma-separated) when
    multiple access rights are missing. For example, creating a regular file
    in a directory that lacks both ``make_reg`` and ``refer`` rights would show
    ``blockers=fs.make_reg,fs.refer``.

    The object identification fields (path, dev, ino for filesystem; opid,
    ocomm for signals) depend on the type of access being blocked and provide
    context about what resource was involved in the denial.


AUDIT_LANDLOCK_DOMAIN
    This record type describes the status of a Landlock domain.  The ``status``
    field can be either ``allocated`` or ``deallocated``.
@@ -86,7 +117,7 @@ This command generates two events, each identified with a unique serial
number following a timestamp (``msg=audit(1729738800.268:30)``).  The first
event (serial ``30``) contains 4 records.  The first record
(``type=LANDLOCK_ACCESS``) shows an access denied by the domain `1a6fdc66f`.
The cause of this denial is signal scopping restriction
The cause of this denial is signal scoping restriction
(``blockers=scope.signal``).  The process that would have receive this signal
is the init process (``opid=1 ocomm="systemd"``).

+93 −12
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ Landlock: unprivileged access control
=====================================

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

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
@@ -142,11 +142,11 @@ This enables the creation of an inclusive ruleset that will contain our rules.
    }

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.
descriptor referring to this ruleset.  The rule will allow reading and
executing 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

@@ -191,10 +191,24 @@ number for a specific action: HTTPS connections.
    err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
                            &net_port, 0);

When passing a non-zero ``flags`` argument to ``landlock_restrict_self()``, a
similar backwards compatibility check is needed for the restrict flags
(see sys_landlock_restrict_self() documentation for available flags):

.. code-block:: c

    __u32 restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON;
    if (abi < 7) {
        /* Clear logging flags unsupported before ABI 7. */
        restrict_flags &= ~(LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF |
                            LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON |
                            LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF);
    }

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.
allowing read and execute access to ``/usr`` while denying all other handled
accesses for the filesystem, and a second rule allowing HTTPS connections.

.. code-block:: c

@@ -208,7 +222,7 @@ The current thread is now ready to sandbox itself with the ruleset.

.. code-block:: c

    if (landlock_restrict_self(ruleset_fd, 0)) {
    if (landlock_restrict_self(ruleset_fd, restrict_flags)) {
        perror("Failed to enforce ruleset");
        close(ruleset_fd);
        return 1;
@@ -431,9 +445,68 @@ system call:
        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.
All Landlock kernel interfaces are supported by the first ABI version unless
explicitly noted in their documentation.

Landlock errata
---------------

In addition to ABI versions, Landlock provides an errata mechanism to track
fixes for issues that may affect backwards compatibility or require userspace
awareness.  The errata bitmask can be queried using:

.. code-block:: c

    int errata;

    errata = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_ERRATA);
    if (errata < 0) {
        /* Landlock not available or disabled */
        return 0;
    }

The returned value is a bitmask where each bit represents a specific erratum.
If bit N is set (``errata & (1 << (N - 1))``), then erratum N has been fixed
in the running kernel.

.. warning::

   **Most applications should NOT check errata.** In 99.9% of cases, checking
   errata is unnecessary, increases code complexity, and can potentially
   decrease protection if misused.  For example, disabling the sandbox when an
   erratum is not fixed could leave the system less secure than using
   Landlock's best-effort protection.  When in doubt, ignore errata.

.. kernel-doc:: security/landlock/errata/abi-4.h
    :doc: erratum_1

.. kernel-doc:: security/landlock/errata/abi-6.h
    :doc: erratum_2

.. kernel-doc:: security/landlock/errata/abi-1.h
    :doc: erratum_3

How to check for errata
~~~~~~~~~~~~~~~~~~~~~~~

If you determine that your application needs to check for specific errata,
use this pattern:

.. code-block:: c

    int errata = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_ERRATA);
    if (errata >= 0) {
        /* Check for specific erratum (1-indexed) */
        if (errata & (1 << (erratum_number - 1))) {
            /* Erratum N is fixed in this kernel */
        } else {
            /* Erratum N is NOT fixed - consider implications for your use case */
        }
    }

**Important:** Only check errata if your application specifically relies on
behavior that changed due to the fix.  The fixes generally make Landlock less
restrictive or more correct, not more restrictive.

Kernel interface
================
@@ -604,6 +677,14 @@ Landlock audit events with the ``LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF``,
sys_landlock_restrict_self().  See Documentation/admin-guide/LSM/landlock.rst
for more details on audit.

Thread synchronization (ABI < 8)
--------------------------------

Starting with the Landlock ABI version 8, it is now possible to
enforce Landlock rulesets across all threads of the calling process
using the ``LANDLOCK_RESTRICT_SELF_TSYNC`` flag passed to
sys_landlock_restrict_self().

.. _kernel_support:

Kernel support
+22 −8
Original line number Diff line number Diff line
@@ -117,11 +117,24 @@ struct landlock_ruleset_attr {
 *     future nested domains, not the one being created. It can also be used
 *     with a @ruleset_fd value of -1 to mute subdomain logs without creating a
 *     domain.
 *
 * The following flag supports policy enforcement in multithreaded processes:
 *
 * %LANDLOCK_RESTRICT_SELF_TSYNC
 *     Applies the new Landlock configuration atomically to all threads of the
 *     current process, including the Landlock domain and logging
 *     configuration. This overrides the Landlock configuration of sibling
 *     threads, irrespective of previously established Landlock domains and
 *     logging configurations on these threads.
 *
 *     If the calling thread is running with no_new_privs, this operation
 *     enables no_new_privs on the sibling threads as well.
 */
/* clang-format off */
#define LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF		(1U << 0)
#define LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON			(1U << 1)
#define LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF		(1U << 2)
#define LANDLOCK_RESTRICT_SELF_TSYNC				(1U << 3)
/* clang-format on */

/**
@@ -182,11 +195,13 @@ struct landlock_net_port_attr {
	 * It should be noted that port 0 passed to :manpage:`bind(2)` will bind
	 * to an available port from the ephemeral port range.  This can be
	 * configured with the ``/proc/sys/net/ipv4/ip_local_port_range`` sysctl
	 * (also used for IPv6).
	 * (also used for IPv6), and within that range, on a per-socket basis
	 * with ``setsockopt(IP_LOCAL_PORT_RANGE)``.
	 *
	 * A Landlock rule with port 0 and the ``LANDLOCK_ACCESS_NET_BIND_TCP``
	 * A Landlock rule with port 0 and the %LANDLOCK_ACCESS_NET_BIND_TCP
	 * right means that requesting to bind on port 0 is allowed and it will
	 * automatically translate to binding on the related port range.
	 * automatically translate to binding on a kernel-assigned ephemeral
	 * port.
	 */
	__u64 port;
};
@@ -329,13 +344,12 @@ struct landlock_net_port_attr {
 * These flags enable to restrict a sandboxed process to a set of network
 * actions.
 *
 * This is supported since Landlock ABI version 4.
 *
 * The following access rights apply to TCP port numbers:
 *
 * - %LANDLOCK_ACCESS_NET_BIND_TCP: Bind a TCP socket to a local port.
 * - %LANDLOCK_ACCESS_NET_CONNECT_TCP: Connect an active TCP socket to
 *   a remote port.
 * - %LANDLOCK_ACCESS_NET_BIND_TCP: Bind TCP sockets to the given local
 *   port. Support added in Landlock ABI version 4.
 * - %LANDLOCK_ACCESS_NET_CONNECT_TCP: Connect TCP sockets to the given
 *   remote port. Support added in Landlock ABI version 4.
 */
/* clang-format off */
#define LANDLOCK_ACCESS_NET_BIND_TCP			(1ULL << 0)
+9 −2
Original line number Diff line number Diff line
obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o

landlock-y := setup.o syscalls.o object.o ruleset.o \
	cred.o task.o fs.o
landlock-y := \
	setup.o \
	syscalls.o \
	object.o \
	ruleset.o \
	cred.o \
	task.o \
	fs.o \
	tsync.o

landlock-$(CONFIG_INET) += net.o

Loading