The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Justin Suess <utilityemal77@gmail.com>
To: gnoack3000@gmail.com, mic@digikod.net
Cc: linux-kernel@vger.kernel.org,
	linux-security-module@vger.kernel.org,
	Justin Suess <utilityemal77@gmail.com>
Subject: [PATCH v4 0/5] Implement LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS
Date: Sun,  9 Aug 2026 11:45:18 -0400	[thread overview]
Message-ID: <20260809154544.1253100-1-utilityemal77@gmail.com> (raw)

Howdy

This series adds a new landlock_restrict_self(2) flag:
LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS.

The flag sets the no_new_privs attribute of the calling thread only
once the enforcement of the ruleset succeeded: no_new_privs is set if
and only if the landlock_restrict_self(2) call succeeds.

Semantics:

A single call replaces the usual prctl(PR_SET_NO_NEW_PRIVS) +
landlock_restrict_self(2) pair.  Because no_new_privs is set by the
call itself, the no_new_privs/CAP_SYS_ADMIN precondition is fulfilled
by construction, so the flag is usable by unprivileged processes.  This
is safe for the same reason the prctl(2) pair is: the executed programs
can either gain privileges or be restricted, never both.

The two states cannot diverge.  A failed call (invalid ruleset FD,
E2BIG, ENOMEM, interrupted TSYNC, ...) leaves no_new_privs unchanged,
and a successful call never returns without no_new_privs set: the
attribute is set past the last point of failure, right before
commit_creds(), which cannot fail.

Combined with LANDLOCK_RESTRICT_SELF_TSYNC, no_new_privs is set on all
threads with the same guarantee: each sibling thread sets it in the
commit phase of the TSYNC protocol, after its all-or-nothing barrier,
so either every thread gets both the domain and no_new_privs, or none
does.  This also makes it possible to set no_new_privs process-wide in
one call, which prctl(2) cannot do.

The flag requires a ruleset: calls with a ruleset_fd of -1 are
rejected.  Such a call would be nothing more than a Landlock-flavored
prctl(PR_SET_NO_NEW_PRIVS), and rejecting it keeps the option of giving
it a meaning later.

Following Mickaël's feedback on v3 [1], a new preparatory patch first
moves the no_new_privs/CAP_SYS_ADMIN check after the flags check, in
the same order as seccomp(2).  Unprivileged callers passing unknown
flag bits now consistently get EINVAL instead of EPERM, whether or not
the new flag is involved; the selftests pin this error ordering.

The Landlock ABI version is bumped to 11.

Test coverage:

base_test checks that a successful call sets no_new_privs without a
prior prctl(2) nor CAP_SYS_ADMIN, that a failed call (invalid ruleset
FD or layer maximum) leaves it unchanged, that the flag requires a
ruleset FD, and the flags-before-privileges error ordering.
tsync_test checks, through variants of a common multi_threaded
fixture, that TSYNC sets no_new_privs on sibling threads along with
the domain, and that a TSYNC call failing on the layer maximum leaves
it unset on every thread.

Changes since v3:

- New preparatory patch: check the landlock_restrict_self(2) flags
  before the no_new_privs/CAP_SYS_ADMIN requirement, like seccomp(2),
  per Mickaël's feedback.  The EINVAL/EPERM visible change now stems
  from this patch instead of the new flag.
- Folded the minimal selftest changes (ABI version, last-flag, and
  checks-ordering updates) into the main patch to keep the series
  bisectable, following the commit tweaked by Mickaël in his next
  branch.
- Dropped the set_no_new_privs local variable; the flag is now checked
  directly at both use sites.
- Turned the multi_threaded_{success,no_new_privs,
  no_new_privs_max_layers} tests into variants of a common
  multi_threaded fixture.
- Reworded the documentation: removed the ambiguous "it"s in the
  tutorial paragraph on CAP_SYS_ADMIN, and used the suggested
  "call (or CAP_SYS_ADMIN use)" wording in both the compatibility
  section and the uapi kdoc.

Per-patch changelogs are below each patch.

[1] https://lore.kernel.org/linux-security-module/20260803223109.707353-1-utilityemal77@gmail.com/

Justin Suess (5):
  landlock: Check landlock_restrict_self(2)'s flags before privileges
  landlock: Add LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS
  selftests/landlock: Test LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS
  landlock: Document LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS
  samples/landlock: Add LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS to sampler

 Documentation/userspace-api/landlock.rst      |  47 +++++++-
 include/uapi/linux/landlock.h                 |  13 +++
 samples/landlock/sandboxer.c                  |  16 ++-
 security/landlock/limits.h                    |   2 +-
 security/landlock/syscalls.c                  |  35 ++++--
 security/landlock/tsync.c                     |   8 +-
 security/landlock/tsync.h                     |   4 +-
 tools/testing/selftests/landlock/base_test.c  | 104 +++++++++++++++++-
 tools/testing/selftests/landlock/tsync_test.c |  96 ++++++++++++++--
 9 files changed, 283 insertions(+), 42 deletions(-)

-- 
2.55.0


             reply	other threads:[~2026-08-09 15:45 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-09 15:45 Justin Suess [this message]
2026-08-09 15:45 ` [PATCH v4 1/5] landlock: Check landlock_restrict_self(2)'s flags before privileges Justin Suess
2026-08-09 15:45 ` [PATCH v4 3/5] selftests/landlock: Test LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS Justin Suess
2026-08-09 15:45 ` [PATCH v4 4/5] landlock: Document LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS Justin Suess
2026-08-09 15:45 ` [PATCH v4 5/5] samples/landlock: Add LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS to sampler Justin Suess
2026-08-09 15:53 ` [PATCH v4 0/5] Implement LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS Justin Suess
2026-08-09 21:24 ` [PATCH v4 2/5] landlock: Add LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS Justin Suess

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=20260809154544.1253100-1-utilityemal77@gmail.com \
    --to=utilityemal77@gmail.com \
    --cc=gnoack3000@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mic@digikod.net \
    /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