archive mirror
 help / color / mirror / Atom feed
From: "Mickaël Salaün" <>
To: James Morris <>, Jann Horn <>,
	"Serge E . Hallyn" <>
Cc: "Mickaël Salaün" <>,
	"Al Viro" <>,
	"Andy Lutomirski" <>,
	"Anton Ivanov" <>,
	"Arnd Bergmann" <>,
	"Casey Schaufler" <>,
	"Jeff Dike" <>,
	"Jonathan Corbet" <>,
	"Kees Cook" <>,
	"Michael Kerrisk" <>,
	"Richard Weinberger" <>,
	"Shuah Khan" <>,
	"Vincent Dagonneau" <>,,,,,,,,,,
	"Mickaël Salaün" <>
Subject: [PATCH v26 12/12] landlock: Add user and kernel documentation
Date: Wed,  9 Dec 2020 20:28:39 +0100	[thread overview]
Message-ID: <> (raw)
In-Reply-To: <>

From: Mickaël Salaün <>

This documentation can be built with the Sphinx framework.

Cc: James Morris <>
Cc: Kees Cook <>
Cc: Serge E. Hallyn <>
Signed-off-by: Mickaël Salaün <>
Reviewed-by: Vincent Dagonneau <>
Reviewed-by: Jann Horn <>

Changes since v24:
* Add Reviewed-by: Jann Horn <>
* Add a paragraph to explain how the ruleset layers work.
* Bump date.

Changes since v23:
* Explain limitations for the maximum number of stacked ruleset, and the
  memory usage restrictions.

Changes since v22:
* Fix spelling and remove obsolete sentence (spotted by Jann Horn).
* Bump date.

Changes since v21:
* Move the user space documentation to userspace-api/landlock.rst and
  the kernel documentation to security/landlock.rst .
* Add license headers.
* Add last update dates.
* Update MAINTAINERS file.
* Add (back) links to .
* Fix spelling.

Changes since v20:
* Update examples and documentation with the new syscalls.

Changes since v19:
* Update examples and documentation with the new syscalls.

Changes since v15:
* Add current limitations.

Changes since v14:
* Fix spelling (contributed by Randy Dunlap).
* Extend documentation about inheritance and explain layer levels.
* Remove the use of now-removed access rights.
* Use GitHub links.
* Improve kernel documentation.
* Add section for tests.
* Update example.

Changes since v13:
* Rewrote the documentation according to the major revamp.

Previous changes:
 Documentation/security/index.rst         |   1 +
 Documentation/security/landlock.rst      |  79 +++++++
 Documentation/userspace-api/index.rst    |   1 +
 Documentation/userspace-api/landlock.rst | 280 +++++++++++++++++++++++
 MAINTAINERS                              |   2 +
 5 files changed, 363 insertions(+)
 create mode 100644 Documentation/security/landlock.rst
 create mode 100644 Documentation/userspace-api/landlock.rst

diff --git a/Documentation/security/index.rst b/Documentation/security/index.rst
index 8129405eb2cc..16335de04e8c 100644
--- a/Documentation/security/index.rst
+++ b/Documentation/security/index.rst
@@ -16,3 +16,4 @@ Security Documentation
+   landlock
diff --git a/Documentation/security/landlock.rst b/Documentation/security/landlock.rst
new file mode 100644
index 000000000000..92317b2ad732
--- /dev/null
+++ b/Documentation/security/landlock.rst
@@ -0,0 +1,79 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. Copyright © 2017-2020 Mickaël Salaün <>
+.. Copyright © 2019-2020 ANSSI
+Landlock LSM: kernel documentation
+:Author: Mickaël Salaün
+:Date: December 2020
+Landlock's goal is to create scoped access-control (i.e. sandboxing).  To
+harden a whole system, this feature should be available to any process,
+including unprivileged ones.  Because such process may be compromised or
+backdoored (i.e. untrusted), Landlock's features must be safe to use from the
+kernel and other processes point of view.  Landlock's interface must therefore
+expose a minimal attack surface.
+Landlock is designed to be usable by unprivileged processes while following the
+system security policy enforced by other access control mechanisms (e.g. DAC,
+LSM).  Indeed, a Landlock rule shall not interfere with other access-controls
+enforced on the system, only add more restrictions.
+Any user can enforce Landlock rulesets on their processes.  They are merged and
+evaluated according to the inherited ones in a way that ensures that only more
+constraints can be added.
+User space documentation can be found here: :doc:`/userspace-api/landlock`.
+Guiding principles for safe access controls
+* A Landlock rule shall be focused on access control on kernel objects instead
+  of syscall filtering (i.e. syscall arguments), which is the purpose of
+  seccomp-bpf.
+* To avoid multiple kinds of side-channel attacks (e.g. leak of security
+  policies, CPU-based attacks), Landlock rules shall not be able to
+  programmatically communicate with user space.
+* Kernel access check shall not slow down access request from unsandboxed
+  processes.
+* Computation related to Landlock operations (e.g. enforcing a ruleset) shall
+  only impact the processes requesting them.
+Userspace tests for backward compatibility, ptrace restrictions and filesystem
+support can be found here: `tools/testing/selftests/landlock/`_.
+Kernel structures
+.. kernel-doc:: security/landlock/object.h
+    :identifiers:
+Ruleset and domain
+A domain is a read-only ruleset tied to a set of subjects (i.e. tasks'
+credentials).  Each time a ruleset is enforced on a task, the current domain is
+duplicated and the ruleset is imported as a new layer of rules in the new
+domain.  Indeed, once in a domain, each rule is tied to a layer level.  To
+grant access to an object, at least one rule of each layer must allow the
+requested action on the object.  A task can then only transit to a new domain
+which is the intersection of the constraints from the current domain and those
+of a ruleset provided by the task.
+The definition of a subject is implicit for a task sandboxing itself, which
+makes the reasoning much easier and helps avoid pitfalls.
+.. kernel-doc:: security/landlock/ruleset.h
+    :identifiers:
+.. Links
+.. _tools/testing/selftests/landlock/:
diff --git a/Documentation/userspace-api/index.rst b/Documentation/userspace-api/index.rst
index acd2cc2a538d..01f1748ab569 100644
--- a/Documentation/userspace-api/index.rst
+++ b/Documentation/userspace-api/index.rst
@@ -18,6 +18,7 @@ place where this information is gathered.
+   landlock
diff --git a/Documentation/userspace-api/landlock.rst b/Documentation/userspace-api/landlock.rst
new file mode 100644
index 000000000000..84aea5478acc
--- /dev/null
+++ b/Documentation/userspace-api/landlock.rst
@@ -0,0 +1,280 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. Copyright © 2017-2020 Mickaël Salaün <>
+.. Copyright © 2019-2020 ANSSI
+Landlock: unprivileged access control
+:Author: Mickaël Salaün
+:Date: December 2020
+The goal of Landlock is to enable to restrict ambient rights (e.g. global
+filesystem access) for a set of processes.  Because Landlock is a stackable
+LSM, it makes 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.
+Landlock rules
+A Landlock rule describes an action on an object.  An object is currently a
+file hierarchy, and the related filesystem actions are defined in `Access
+rights`_.  A set of rules is aggregated in a ruleset, which can then restrict
+the thread enforcing it, and its future children.
+Defining and enforcing a security policy
+We first need to create the ruleset that will contain our rules.  For this
+example, the ruleset will contain rules which only allow read actions, but
+write actions will be denied.  The ruleset then needs to handle both of these
+kind of actions.
+.. code-block:: c
+    int ruleset_fd;
+    struct landlock_ruleset_attr ruleset_attr = {
+        .handled_access_fs =
+    };
+    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
+.. code-block:: c
+    int err;
+    struct landlock_path_beneath_attr path_beneath = {
+        .allowed_access =
+    };
+    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;
+    }
+We now have a ruleset with one rule allowing read access to ``/usr`` while
+denying all other handled accesses for the filesystem.  The next step is to
+restrict the current thread from gaining more privileges (e.g. thanks to a SUID
+.. 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_enforce_ruleset_current(ruleset_fd, 0)) {
+        perror("Failed to enforce ruleset");
+        close(ruleset_fd);
+        return 1;
+    }
+    close(ruleset_fd);
+If the `landlock_enforce_ruleset_current` 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, merge of their parent one (if
+any) with the new ruleset.
+Full working code can be found in `samples/landlock/sandboxer.c`_.
+Every new thread resulting from a :manpage:`clone(2)` inherits Landlock domain
+restrictions from its parent.  This is similar to the seccomp inheritance (cf.
+:doc:`/userspace-api/seccomp_filter`) 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.
+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
+A sandboxed thread can add more constraints to itself with a new enforced
+ruleset.  This complementary policy inherits from the previous enforced
+rulesets.  Access to a file path is granted if, for each policy layer, at least
+one rule encountered on the path (from the file to the root) grants the access.
+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 subset of the target process rules,
+which means the tracee must be in a sub-domain of the tracer.
+Kernel interface
+Access rights
+.. kernel-doc:: include/uapi/linux/landlock.h
+    :identifiers: fs_access
+Creating a new ruleset
+.. kernel-doc:: security/landlock/syscall.c
+    :identifiers: sys_landlock_create_ruleset
+.. kernel-doc:: include/uapi/linux/landlock.h
+    :identifiers: landlock_ruleset_attr
+Extending a ruleset
+.. kernel-doc:: security/landlock/syscall.c
+    :identifiers: sys_landlock_add_rule
+.. kernel-doc:: include/uapi/linux/landlock.h
+    :identifiers: landlock_rule_type landlock_path_beneath_attr
+Enforcing a ruleset
+.. kernel-doc:: security/landlock/syscall.c
+    :identifiers: sys_landlock_enforce_ruleset_current
+Current limitations
+Ruleset layers
+There is a limit of 64 layers of stacked rulesets.  This can be an issue for a
+task willing to enforce a new ruleset in complement to its 64 inherited
+rulesets.  Once this limit is reached, sys_landlock_enforce_ruleset_current()
+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 which may also want to sandbox themselves (e.g. shells, container
+managers, etc.).
+Memory usage
+Kernel memory allocated to create rulesets is accounted and can be restricted
+by the :doc:`/admin-guide/cgroup-v1/memory`.
+File renaming and linking
+Because Landlock targets unprivileged access controls, it is needed to properly
+handle composition of rules.  Such property also implies rules nesting.
+Properly handling multiple layers of ruleset, each one of them able to restrict
+access to files, also implies to inherit 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 imply to
+propagate the hierarchy constraints.  To protect against privilege escalations
+through renaming or linking, and for the sack of simplicity, Landlock currently
+limits linking and renaming to the same directory.  Future Landlock evolutions
+will enable more flexibility for renaming and linking, with dedicated ruleset
+An OverlayFS mount point consists of upper and lower layers.  It is currently
+not possible to reliably infer which underlying file hierarchy matches an
+OverlayFS path composed of such layers.  It is then not currently possible to
+track the source of an indirect access request, and then not possible to
+properly identify and allow an unified OverlayFS hierarchy.  Restricting files
+in an OverlayFS mount point works, but files allowed in one layer may not be
+allowed in a related OverlayFS mount point.  A future Landlock evolution will
+make possible to properly work with OverlayFS, according to a dedicated ruleset
+Special filesystems
+Access to regular files and directories can be restricted by Landlock,
+according to the handled accesses of a ruleset.  However, files which do not
+come from a user-visible filesystem (e.g. pipe, socket), but can still be
+accessed through /proc/self/fd/, cannot currently be restricted.  Likewise,
+some special kernel filesystems such as nsfs which can be accessed through
+/proc/self/ns/, cannot currently be restricted.  For now, these kind of special
+paths are then always allowed.  Future Landlock evolutions will enable to
+restrict such paths, with dedicated ruleset flags.
+Questions and answers
+What about user space sandbox managers?
+Using user space process to enforce restrictions on kernel resources can lead
+to race conditions or inconsistent evaluations (i.e. `Incorrect mirroring of
+the OS code and state
+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 <>`_).
+Additional documentation
+* :doc:`/security/landlock`
+.. Links
+.. _samples/landlock/sandboxer.c:
index 8656d3b9dd0e..dc9c07809f6f 100644
@@ -9833,6 +9833,8 @@ L:
 S:	Supported
 T:	git
+F:	Documentation/security/landlock.rst
+F:	Documentation/userspace-api/landlock.rst
 F:	include/uapi/linux/landlock.h
 F:	security/landlock/
 K:	landlock

  parent reply	other threads:[~2020-12-09 19:33 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-09 19:28 [PATCH v26 00/12] Landlock LSM Mickaël Salaün
2020-12-09 19:28 ` [PATCH v26 01/12] landlock: Add object management Mickaël Salaün
2020-12-09 19:28 ` [PATCH v26 02/12] landlock: Add ruleset and domain management Mickaël Salaün
2021-01-14  3:21   ` Jann Horn
2020-12-09 19:28 ` [PATCH v26 03/12] landlock: Set up the security framework and manage credentials Mickaël Salaün
2020-12-09 19:28 ` [PATCH v26 04/12] landlock: Add ptrace restrictions Mickaël Salaün
2020-12-09 19:28 ` [PATCH v26 05/12] LSM: Infrastructure management of the superblock Mickaël Salaün
2020-12-09 19:28 ` [PATCH v26 06/12] fs,security: Add sb_delete hook Mickaël Salaün
2020-12-09 19:28 ` [PATCH v26 07/12] landlock: Support filesystem access-control Mickaël Salaün
2021-01-14  3:22   ` Jann Horn
2021-01-14 18:54     ` Mickaël Salaün
2021-01-14 22:43       ` Jann Horn
2021-01-15  9:10         ` Mickaël Salaün
2021-01-15 18:31           ` Jann Horn
2021-01-16 17:16             ` Mickaël Salaün
2020-12-09 19:28 ` [PATCH v26 08/12] landlock: Add syscall implementations Mickaël Salaün
2020-12-10 10:38   ` Mickaël Salaün
2020-12-09 19:28 ` [PATCH v26 09/12] arch: Wire up Landlock syscalls Mickaël Salaün
2020-12-09 19:28 ` [PATCH v26 10/12] selftests/landlock: Add user space tests Mickaël Salaün
2020-12-09 19:28 ` [PATCH v26 11/12] samples/landlock: Add a sandbox manager example Mickaël Salaün
2021-01-14  3:21   ` Jann Horn
2021-01-14 18:59     ` Mickaël Salaün
2020-12-09 19:28 ` Mickaël Salaün [this message]
2021-01-14  3:22 ` [PATCH v26 00/12] Landlock LSM Jann Horn
2021-01-14 19:03   ` Mickaël Salaün

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).