From: "Günther Noack" <gnoack3000@gmail.com>
To: Shi Lecun <shilc2025@mail.sustech.edu.cn>
Cc: mic <mic@digikod.net>, gnoack <gnoack@google.com>,
linux-security-module <linux-security-module@vger.kernel.org>,
"张锋巍(ZHANG Fengwei)" <zhangfw@sustech.edu.cn>,
"Bryam Vargas" <hexlabsecurity@proton.me>
Subject: Re: [RFC] landlock: clarify signal scoping for pre-existing f_owner registrations
Date: Sat, 7 Nov 2026 15:18:30 +0100 [thread overview]
Message-ID: <20261107.2f1fa9977739@gnoack.org> (raw)
In-Reply-To: <tencent_1D938EDA50BCDB080CFADC6A@qq.com>
Hello Shi!
On Sat, Nov 07, 2026 at 12:23:35PM +0800, Shi Lecun wrote:
> While investigating LANDLOCK_SCOPE_SIGNAL, I noticed that the current
> documentation does not describe how signal scoping interacts with
> asynchronous notifications registered before the scope is enforced.
>
> A minimal reproducer performs the following steps as an unprivileged user:
>
> 1. Create a pipe and use fcntl(F_SETOWN) to select a same-UID process
> outside the future Landlock domain as the notification recipient.
> 2. Configure F_SETSIG and O_ASYNC.
> 3. Add a Landlock layer handling LANDLOCK_SCOPE_SIGNAL.
> 4. Write to the pipe.
>
> The configured signal is still delivered to the out-of-domain process.
> Using F_SETSIG(SIGKILL) makes this especially visible by terminating the
> recipient. In contrast:
>
> - kill(2) after enforcing LANDLOCK_SCOPE_SIGNAL fails with EPERM;
> - registering f_owner after enforcing the scope does not result in
> out-of-domain signal delivery.
>
> I reproduced this matrix on 7.2.14-arch1-1 with Landlock ABI 10 as UID
> 1000:
>
> direct kill after scope victim survives
> post-scope F_SETOWN victim survives
> pre-scope F_SETOWN victim receives SIGKILL
> FS layer, F_SETOWN, scope victim receives SIGKILL
>
> I also inspected a local kernel tree at commit d68ce4e71248.
> From security/landlock/fs.c and security/landlock/task.c, my
> understanding is that hook_file_set_fowner() saves the applicable
> Landlock subject when F_SETOWN is called, and
> hook_file_send_sigiotask() later checks delivery using that saved
> subject. If no signal-scoped domain applied at registration time, the
> saved domain is NULL and later delivery is not checked against the
> triggering task's newly added domain. The usual UID/EUID checks in
> sigio_perm() still apply.
>
> This also appears to be intentional and covered by the existing
> fown/sandbox_after_setown variant in
> tools/testing/selftests/landlock/scoped_signal_test.c, which expects a
> signal to be received when F_SETOWN happened before sandboxing. I
> therefore do not consider this behavior itself to be a signal-scope
> bypass.
>
> However, Documentation/userspace-api/landlock.rst currently says:
>
> "This limits the sending of signals to target processes which run
> within the same or a nested Landlock domain."
Thanks for the investigation!
The F_SETOWN signaling restriction was not initially covered correctly
by Landlock's signal scoping support, and was discovered and fixed by
Bryam Vargas in [1].
Another signaling-related report we received was about pseudoterminals,
with a documentation patch in the same place, in [2].
It feels that in both the F_SETOWN and the PTY case, the underlying
rationale is the same though -- a signaling mechanism that was set up
prior or independent to Landlock enforcement continues to work.
> Without a lifecycle qualification, this can be read as covering every
> signal delivered after the scope is enforced, including notifications
> whose f_owner was registered earlier. The same section explicitly
> documents the lifetime exception for previously connected UNIX sockets,
> but there is no corresponding explanation for asynchronous signals.
>
> Would it make sense to add a paragraph along these lines?
>
> Asynchronous signal notifications associated with a file owner, such
> as SIGIO and SIGURG, are checked using the Landlock context saved
> when fcntl(F_SETOWN) sets the notification recipient. Adding a
> LANDLOCK_SCOPE_SIGNAL restriction later does not apply that new
> restriction to notifications using the previously saved context.
> Sandboxes that require signal isolation should therefore enforce
> the scope before untrusted code can register asynchronous
> notification recipients, and account for any pre-existing
> registrations on retained file descriptors.
>
> Does this accurately describe the intended userspace semantics?
> If so, I would be happy to send a documentation patch for the IPC
> scoping section.
Your writeup matches my understanding as well, but I am a bit worried
that these corner cases start taking more room in the documentation
than the main point of what that feature does. How about something
shorter, maybe:
For signaling of I/O availability (F_GETSIG(2const)), Landlock
checks are done with respect to the Landlock domain at the time of
fcntl(F_SETOWN).
?
It feels better to link to the existing documentation for such
features instead of trying to describe them correctly.
–Günther
[1] https://lore.kernel.org/all/cover.1780614610.git.hexlabsecurity@proton.me/
[2] https://lore.kernel.org/all/20260923163321.79770-2-clusk@northecho.dev/
next prev parent reply other threads:[~2026-11-07 14:18 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-07 4:23 [RFC] landlock: clarify signal scoping for pre-existing f_owner registrations Shi Lecun
2026-11-07 14:18 ` Günther Noack [this message]
2026-11-08 5:50 ` [PATCH] docs: landlock: clarify F_SETOWN signal scoping Shi Lecun
2026-11-08 16:21 ` Günther Noack
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=20261107.2f1fa9977739@gnoack.org \
--to=gnoack3000@gmail.com \
--cc=gnoack@google.com \
--cc=hexlabsecurity@proton.me \
--cc=linux-security-module@vger.kernel.org \
--cc=mic@digikod.net \
--cc=shilc2025@mail.sustech.edu.cn \
--cc=zhangfw@sustech.edu.cn \
/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