From: Farid Zakaria <farid.m.zakaria@gmail.com>
To: "Mickaël Salaün" <mic@digikod.net>, "Günther Noack" <gnoack@google.com>
Cc: Paul Moore <paul@paul-moore.com>,
James Morris <jmorris@namei.org>,
"Serge E. Hallyn" <serge@hallyn.com>,
Shuah Khan <shuah@kernel.org>, Jonathan Corbet <corbet@lwn.net>,
John Ericson <mail@johnericson.me>,
linux-security-module@vger.kernel.org,
linux-kselftest@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org,
Farid Zakaria <farid.m.zakaria@gmail.com>
Subject: [PATCH RFC 0/3] landlock: Add access rights on created files
Date: Sat, 24 Oct 2026 13:39:16 -0700 [thread overview]
Message-ID: <20261024-landlock-created-rights-v1-0-77c8db3f6bd2@gmail.com> (raw)
This is a proposal for an idea to add support for landlock to work
better with build systems such as Nix where they want to apply
restrictions but the paths may not yet exist.
TL;DR;
========
Landlock rules attach to inodes that exist when a ruleset is built.
That makes a directory shared between trusted and sandboxed tasks hard
to confine: the sandbox may create entries there with
LANDLOCK_ACCESS_FS_MAKE_*, but no rule can name those entries ahead of
time, and granting read access on the directory to cover them exposes
every other entry as well. This series adds a rule flag that grants
access rights on the entries a domain creates in a directory, instead
of on the directory.
Motivation
==========
The motivating user is the Nix build sandbox. Every Nix build runs in
its own sandbox, and a build may only read its declared inputs in
/nix/store and must be able to write and read back the outputs it
creates there. Nix enforces this with a private mount namespace: it
creates an empty store directory and bind-mounts each input path into
it, one mount per input. Nix has paid this per-input cost since the
sandbox was introduced [1].
The cost is paid per build and grows with the size of the input
closure. Nix is moving towards much finer-grained builds (many small
derivations instead of a few large ones), so the number of sandboxes
grows while each build's own work shrinks, and the sandbox setup is
becoming the bottleneck. A typical build has hundreds of inputs; large
ones have thousands.
A microbenchmark sets up and tears down a Nix-like sandbox (user,
mount, PID, IPC, UTS and network namespaces, pivot_root into a chroot,
removing the chroot afterwards). It compares one bind mount per input
with a single bind mount of the whole store plus one Landlock rule per
input. Median latency per sandbox, one sandbox at a time, Linux 7.1,
ext4, 16 cores:
inputs bind mount per input one bind mount + Landlock speedup
10 3.2 ms 2.3 ms 1.4x
100 11.6 ms 2.8 ms 4.1x
1000 79.3 ms 6.4 ms 12.4x
5000 400.1 ms 24.4 ms 16.4x
With Landlock, an input costs an O_PATH open and a landlock_add_rule()
call: there is a single mount, and no mountpoint directory to create
before the build and remove after it (removing the 1000 empty
mountpoints alone took 17 ms).
The single bind mount is only sound if the store listing and the
undeclared store paths stay unreadable while the build can still use
its outputs. Without this series, covering the outputs requires a rule
on /nix/store itself, which makes every store path readable again.
[1] https://github.com/NixOS/nix/issues/179
Series
======
Patch 1 lets an LSM observe inode creation through the
inode_init_security hook when no LSM provides an xattr. Patch 2 adds
the LANDLOCK_ADD_RULE_CREATED flag for path-beneath rules and bumps the
ABI to 13. Patch 3 adds selftests.
Testing
=======
The series applies to the Landlock next branch (3e271a27c46f) and was
tested on Linux 7.3 with that branch applied.
Without patch 2, the five new tests and the ABI version check fail.
Open questions
==============
- A created inode stays pinned until the layer's hierarchy is freed, so a
sandbox that creates many entries in such a directory keeps them all in
memory. Should this be bounded?
- Creation is detected in inode_init_security, so on filesystems that do
not call security_inode_init_security() created entries get no rights.
Is there a better hook?
- Through overlayfs, created entries get no rights either, because the
upper inode is created with the mounter's credentials. Should overlayfs
be handled, e.g. via security_dentry_create_files_as()?
- A file renamed or linked in keeps only the rights it had at its source.
Should it get none instead?
---
Farid Zakaria (3):
lsm: Call inode_init_security hooks without xattrs
landlock: Add access rights on created files
selftests/landlock: Test LANDLOCK_ADD_RULE_CREATED
Documentation/userspace-api/landlock.rst | 42 +++++
include/uapi/linux/landlock.h | 18 +++
security/landlock/domain.c | 182 ++++++++++++++++++++-
security/landlock/domain.h | 28 ++++
security/landlock/fs.c | 176 +++++++++++++++++++--
security/landlock/object.h | 6 +
security/landlock/ruleset.c | 6 +
security/landlock/ruleset.h | 14 ++
security/landlock/syscalls.c | 20 ++-
security/security.c | 9 +-
tools/testing/selftests/landlock/base_test.c | 2 +-
tools/testing/selftests/landlock/fs_test.c | 227 +++++++++++++++++++++++++++
12 files changed, 703 insertions(+), 27 deletions(-)
---
base-commit: 3e271a27c46fd591d1011c7de5a644a41e2010f1
change-id: 20261024-landlock-created-rights-9340b00a8c4d
Best regards,
--
Farid Zakaria <farid.m.zakaria@gmail.com>
next reply other threads:[~2026-10-24 20:39 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-24 20:39 Farid Zakaria [this message]
2026-10-24 20:39 ` [PATCH RFC 1/3] lsm: Call inode_init_security hooks without xattrs Farid Zakaria
2026-10-24 20:39 ` [PATCH RFC 2/3] landlock: Add access rights on created files Farid Zakaria
2026-10-24 20:39 ` [PATCH RFC 3/3] selftests/landlock: Test LANDLOCK_ADD_RULE_CREATED Farid Zakaria
2026-10-24 21:43 ` [PATCH RFC 0/3] landlock: Add access rights on created files Justin Suess
2026-10-24 22:03 ` Justin Suess
2026-10-24 23:59 ` Farid Zakaria
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:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261024-landlock-created-rights-v1-0-77c8db3f6bd2@gmail.com \
--to=farid.m.zakaria@gmail.com \
--cc=corbet@lwn.net \
--cc=gnoack@google.com \
--cc=jmorris@namei.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=mail@johnericson.me \
--cc=mic@digikod.net \
--cc=paul@paul-moore.com \
--cc=serge@hallyn.com \
--cc=shuah@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* 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
all inboxes | Powered by JetHome®