[REPORT] landlock: SCOPE_SIGNAL bypass via F_SETOWN to invoker pgid -> SIGIO/SIGKILL to non-sandboxed targets
hexlabsecurity at proton.me
hexlabsecurity at proton.me
Fri May 29 19:03:18 UTC 2026
Hi Mickaël,
> Could you please replace the reproducer code with a proper kselftest?
> That would need to be a new email patch (v3) [...]
Done -- v3 is a two-patch series:
[PATCH v3 1/2] landlock: fix LANDLOCK_SCOPE_SIGNAL bypass via F_SETOWN to invoker's pgid
[PATCH v3 2/2] selftests/landlock: test SCOPE_SIGNAL on the SIGIO/fowner pgid path
Patch 2 replaces the informal reproducer with a regression test in
scoped_signal_test.c, reusing the existing fown/SIGURG idiom. It adds
TEST(sigio_to_pgid_members): a sandboxed child at the head of its pgid hlist
arms F_SETSIG(SIGURG) / F_SETOWN(-pgrp) / O_ASYNC and triggers the fan-out; the
in-domain child must be signaled (positive control) and the non-sandboxed
parent must not.
I also added the Fixes: tag and Cc: stable that v2 was missing:
Fixes: 18eb75f3af40 ("landlock: Always allow signals between threads of the same process")
That is where the same-thread-group exemption on the fowner path was
introduced (v6.15; backported to 6.12.y/6.13.y/6.14.y -- the original v6.12
signal scoping captured the subject unconditionally and was not affected).
The fix hunk itself is unchanged from v1/v2 and keeps Justin's Tested-by.
A/B on 6.12.90 + CONFIG_SECURITY_LANDLOCK (same .config, only the hunk
differs): without patch 1 the new test fails (the parent is signaled); with it
the test passes and the landlock signal-scoping suite is 20/20. checkpatch is
clean except one expected Reported-by/Closes warning -- the original report was
sent to security at kernel.org, so there is no public URL to point Closes: at.
Thanks,
Bryam Vargas
Independent security researcher. HEXLAB SAS (registration pending) -- Cali, Colombia.
This series fixes a LANDLOCK_SCOPE_SIGNAL bypass on the asynchronous SIGIO
(fcntl(F_SETOWN)) delivery path and adds the kselftest requested in review.
Patch 1 narrows the same-thread-group exemption in control_current_fowner()
so that F_SETOWN to a process group (or session) always captures the caller's
Landlock subject. Without it, a sandboxed task at the head of its pgid hlist
(the default position after fork()) skips the capture, and the SIGIO fan-out
reaches non-sandboxed members of the process group, defeating SCOPE_SIGNAL.
The direct kill() path (hook_task_kill) is unaffected.
Patch 2 adds a regression test to scoped_signal_test.c, replacing the informal
reproducer that previously accompanied the fix.
The defect was introduced by commit 18eb75f3af40 ("landlock: Always allow
signals between threads of the same process") in v6.15, and is present in the
stable branches that backported it (6.12.y, 6.13.y, 6.14.y).
control_current_fowner() is identical across those branches, so patch 1 applies
as-is (stable kernels before the fown_subject conversion store the domain in
landlock_file(file)->fown_domain; the exemption and the fix are the same).
A/B verified on 6.12.90 + CONFIG_SECURITY_LANDLOCK (same .config, only the fix
hunk differs):
- without patch 1: the new test fails -- the non-sandboxed parent receives
the signal (SCOPE_SIGNAL bypassed);
- with patch 1: the new test passes, and the whole landlock signal-scoping
suite passes 20/20 (no regression).
v2 -> v3:
- patch 1: add Fixes: tag and Cc: stable; the fix hunk is unchanged from v1/v2.
- patch 2 (new): replace the git-notes reproducer with a kselftest.
- v1/v2 were sent to security at kernel.org (embargoed; not in a public archive).
Bryam Vargas (2):
landlock: fix LANDLOCK_SCOPE_SIGNAL bypass via F_SETOWN to invoker's pgid
selftests/landlock: test SCOPE_SIGNAL on the SIGIO/fowner pgid path
security/landlock/fs.c | 12 +++
.../selftests/landlock/scoped_signal_test.c | 97 +++++++++++++++++++
2 files changed, 109 insertions(+)
base-commit: 27fa82620cbaa89a7fc11ac3057701d598813e87
More information about the Linux-security-module-archive
mailing list