<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux.git/security/landlock/task.c, branch v7.3-rc2</title>
<subtitle>Linux kernel source tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/'/>
<entry>
<title>landlock: Add tracepoints for ptrace and scope denials</title>
<updated>2026-08-17T08:17:16+00:00</updated>
<author>
<name>Mickaël Salaün</name>
<email>mic@digikod.net</email>
</author>
<published>2026-08-11T09:43:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=bb91730f16c064f4eb0dc15ed27814c8f9aef670'/>
<id>bb91730f16c064f4eb0dc15ed27814c8f9aef670</id>
<content type='text'>
Scope and ptrace denials follow a different code path (a domain
hierarchy check) than access-right denials, so they need dedicated
tracepoints with type-specific TP_PROTO arguments.  Complete the denial
coverage with:
- landlock_deny_ptrace: ptrace access denied by a domain hierarchy
  mismatch.
- landlock_deny_scope_signal: signal delivery denied by
  LANDLOCK_SCOPE_SIGNAL.
- landlock_deny_scope_abstract_unix_socket: abstract unix socket access
  denied by LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET.

TP_PROTO passes the raw kernel object (struct task_struct or struct
sock) for eBPF BTF access; the comm and sun_path string fields use
__print_untrusted_str() because they hold untrusted input.  Unlike the
deny_access events, these omit the blockers field: each maps to exactly
one denial type named by the event, so the bitmask would always be zero.
Like the deny_access events they carry same_exec and logged.

Audit logs the task-targeted denials with generic field names (opid,
ocomm), but a strongly typed trace event can use role-prefixed names
(tracee_pid/tracee_comm, target_pid/target_comm) that match the mainline
task-name convention (sched_process_fork's parent_comm/child_comm) and
say whose name each field holds; a bare comm= would collide across
events.  The abstract-unix-socket event reports peer_pid instead, a
tracepoint-only field with no audit counterpart.

A scope or ptrace verdict compares the subject domain against the other
party's domain, so each event also reports that other party's Landlock
domain (tracee_domain=, target_domain=, or peer_domain=); the subject
domain= alone does not let a consumer redo domain_is_scoped() or
domain_ptrace().  It is reported as a scalar ID rather than a domain
pointer: a domain object is immutable, but the other task can replace
its credential and free the domain that credential referenced, so a
stored foreign pointer could dangle before the event is consumed.  The
scalar ID also honors the tracepoint no-nullable-pointer rule, since the
other party is frequently unsandboxed.  Passing the foreign domain
hierarchy object so an eBPF consumer could walk the other party's
ancestry live would lengthen the RCU section on the shared denial path
and needs a deferred refcount put, so it is left as a future
enhancement.  The relational domain-ID field (tracee_domain,
target_domain, or peer_domain) is trace-only and is not added to audit
records, so audit's denial format is unchanged by this series.

Cc: Günther Noack &lt;gnoack@google.com&gt;
Cc: Justin Suess &lt;utilityemal77@gmail.com&gt;
Cc: Masami Hiramatsu &lt;mhiramat@kernel.org&gt;
Cc: Mathieu Desnoyers &lt;mathieu.desnoyers@efficios.com&gt;
Cc: Steven Rostedt &lt;rostedt@goodmis.org&gt;
Cc: Tingmao Wang &lt;m@maowtm.org&gt;
Link: https://patch.msgid.link/20260811094338.288094-14-mic@digikod.net
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Scope and ptrace denials follow a different code path (a domain
hierarchy check) than access-right denials, so they need dedicated
tracepoints with type-specific TP_PROTO arguments.  Complete the denial
coverage with:
- landlock_deny_ptrace: ptrace access denied by a domain hierarchy
  mismatch.
- landlock_deny_scope_signal: signal delivery denied by
  LANDLOCK_SCOPE_SIGNAL.
- landlock_deny_scope_abstract_unix_socket: abstract unix socket access
  denied by LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET.

TP_PROTO passes the raw kernel object (struct task_struct or struct
sock) for eBPF BTF access; the comm and sun_path string fields use
__print_untrusted_str() because they hold untrusted input.  Unlike the
deny_access events, these omit the blockers field: each maps to exactly
one denial type named by the event, so the bitmask would always be zero.
Like the deny_access events they carry same_exec and logged.

Audit logs the task-targeted denials with generic field names (opid,
ocomm), but a strongly typed trace event can use role-prefixed names
(tracee_pid/tracee_comm, target_pid/target_comm) that match the mainline
task-name convention (sched_process_fork's parent_comm/child_comm) and
say whose name each field holds; a bare comm= would collide across
events.  The abstract-unix-socket event reports peer_pid instead, a
tracepoint-only field with no audit counterpart.

A scope or ptrace verdict compares the subject domain against the other
party's domain, so each event also reports that other party's Landlock
domain (tracee_domain=, target_domain=, or peer_domain=); the subject
domain= alone does not let a consumer redo domain_is_scoped() or
domain_ptrace().  It is reported as a scalar ID rather than a domain
pointer: a domain object is immutable, but the other task can replace
its credential and free the domain that credential referenced, so a
stored foreign pointer could dangle before the event is consumed.  The
scalar ID also honors the tracepoint no-nullable-pointer rule, since the
other party is frequently unsandboxed.  Passing the foreign domain
hierarchy object so an eBPF consumer could walk the other party's
ancestry live would lengthen the RCU section on the shared denial path
and needs a deferred refcount put, so it is left as a future
enhancement.  The relational domain-ID field (tracee_domain,
target_domain, or peer_domain) is trace-only and is not added to audit
records, so audit's denial format is unchanged by this series.

Cc: Günther Noack &lt;gnoack@google.com&gt;
Cc: Justin Suess &lt;utilityemal77@gmail.com&gt;
Cc: Masami Hiramatsu &lt;mhiramat@kernel.org&gt;
Cc: Mathieu Desnoyers &lt;mathieu.desnoyers@efficios.com&gt;
Cc: Steven Rostedt &lt;rostedt@goodmis.org&gt;
Cc: Tingmao Wang &lt;m@maowtm.org&gt;
Link: https://patch.msgid.link/20260811094338.288094-14-mic@digikod.net
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>landlock: Split denial logging from audit into common framework</title>
<updated>2026-08-17T08:17:11+00:00</updated>
<author>
<name>Mickaël Salaün</name>
<email>mic@digikod.net</email>
</author>
<published>2026-08-11T09:43:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=e761a88cedeb46de17b6d9e8c7c41c7671e83a6b'/>
<id>e761a88cedeb46de17b6d9e8c7c41c7671e83a6b</id>
<content type='text'>
Tracepoint emission requires the denial framework (layer identification,
request validation) without depending on CONFIG_AUDIT.  Separate the
denial logging infrastructure from the audit-specific code by
introducing a common log framework.

Create CONFIG_SECURITY_LANDLOCK_LOG, enabled by default when
CONFIG_AUDIT is set; a following commit extends it to CONFIG_TRACEPOINTS
when the first tracepoint consumer is added.  Move the common framework
(the request types, the layer identification and request validation, and
the landlock_log_denial() and landlock_log_free_domain() entry points)
into log.c and log.h, and keep the audit-specific record formatting in
audit.c. log.o is built for CONFIG_SECURITY_LANDLOCK_LOG and audit.o for
CONFIG_AUDIT, so the common framework is available to a tracepoints-only
build.  The entry points dispatch to no-op static inline audit stubs
without CONFIG_AUDIT, so the call sites stay unconditional.  Rename the
former landlock_log_drop_domain() to landlock_log_free_domain() to match
the landlock_free_domain tracepoint added in a following commit.

landlock_log_denial() counts denials even without audit, so its
declaration and no-op stub are guarded by CONFIG_SECURITY_LANDLOCK_LOG,
not CONFIG_AUDIT; a CONFIG_AUDIT guard would expose the stub and clash
with log.c's definition in a tracepoints-only build.

Widen the ID allocation (id.o and the landlock_init_id() /
landlock_get_id_range() declarations) and the log-state representation
(the domain_exec and log_subdomains_off credential fields, the
landlock_hierarchy log fields, and the code that maintains them) from
CONFIG_AUDIT to CONFIG_SECURITY_LANDLOCK_LOG, so each field and its
writer share one guard and are available to tracing without audit
support.

Widen the denial-path state that feeds the per-denial logging decision
the same way, so the "logged" verdict is computed identically whether or
not CONFIG_AUDIT is set.  Widening fown_layer is what keeps the
file-owner-signal path valid without audit: otherwise
hook_file_send_sigiotask() would leave layer_plus_one at zero, tripping
the is_valid_request() canary and dropping the LANDLOCK_SCOPE_SIGNAL
denial from tracing.

The ruleset-level quiet_masks stays on no CONFIG guard: it is builder
state validated and stored from user input, kept available so
LANDLOCK_ADD_RULE_QUIET flags are accepted and ignored, not rejected,
when CONFIG_SECURITY_LANDLOCK_LOG is disabled.

Cc: Günther Noack &lt;gnoack@google.com&gt;
Link: https://patch.msgid.link/20260811094338.288094-5-mic@digikod.net
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Tracepoint emission requires the denial framework (layer identification,
request validation) without depending on CONFIG_AUDIT.  Separate the
denial logging infrastructure from the audit-specific code by
introducing a common log framework.

Create CONFIG_SECURITY_LANDLOCK_LOG, enabled by default when
CONFIG_AUDIT is set; a following commit extends it to CONFIG_TRACEPOINTS
when the first tracepoint consumer is added.  Move the common framework
(the request types, the layer identification and request validation, and
the landlock_log_denial() and landlock_log_free_domain() entry points)
into log.c and log.h, and keep the audit-specific record formatting in
audit.c. log.o is built for CONFIG_SECURITY_LANDLOCK_LOG and audit.o for
CONFIG_AUDIT, so the common framework is available to a tracepoints-only
build.  The entry points dispatch to no-op static inline audit stubs
without CONFIG_AUDIT, so the call sites stay unconditional.  Rename the
former landlock_log_drop_domain() to landlock_log_free_domain() to match
the landlock_free_domain tracepoint added in a following commit.

landlock_log_denial() counts denials even without audit, so its
declaration and no-op stub are guarded by CONFIG_SECURITY_LANDLOCK_LOG,
not CONFIG_AUDIT; a CONFIG_AUDIT guard would expose the stub and clash
with log.c's definition in a tracepoints-only build.

Widen the ID allocation (id.o and the landlock_init_id() /
landlock_get_id_range() declarations) and the log-state representation
(the domain_exec and log_subdomains_off credential fields, the
landlock_hierarchy log fields, and the code that maintains them) from
CONFIG_AUDIT to CONFIG_SECURITY_LANDLOCK_LOG, so each field and its
writer share one guard and are available to tracing without audit
support.

Widen the denial-path state that feeds the per-denial logging decision
the same way, so the "logged" verdict is computed identically whether or
not CONFIG_AUDIT is set.  Widening fown_layer is what keeps the
file-owner-signal path valid without audit: otherwise
hook_file_send_sigiotask() would leave layer_plus_one at zero, tripping
the is_valid_request() canary and dropping the LANDLOCK_SCOPE_SIGNAL
denial from tracing.

The ruleset-level quiet_masks stays on no CONFIG guard: it is builder
state validated and stored from user input, kept available so
LANDLOCK_ADD_RULE_QUIET flags are accepted and ignored, not rejected,
when CONFIG_SECURITY_LANDLOCK_LOG is disabled.

Cc: Günther Noack &lt;gnoack@google.com&gt;
Link: https://patch.msgid.link/20260811094338.288094-5-mic@digikod.net
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>landlock: Split struct landlock_domain from struct landlock_ruleset</title>
<updated>2026-08-17T08:17:11+00:00</updated>
<author>
<name>Mickaël Salaün</name>
<email>mic@digikod.net</email>
</author>
<published>2026-08-11T09:43:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=38411604162e6abe02741d3c364a4df46d6f612f'/>
<id>38411604162e6abe02741d3c364a4df46d6f612f</id>
<content type='text'>
Switch all domain users to the new struct landlock_domain type
introduced by a previous commit, eliminating the conflation between
mutable rulesets and immutable domains. landlock_merge_ruleset() now
returns and allocates a struct landlock_domain, and the merge and
inherit helpers move next to it; the former static insert_rule() is
exported as landlock_store_rule() for its new caller across the
translation-unit boundary.

The merge destination is now a private struct landlock_domain still
under construction (owned by the calling thread, not yet shared), so the
merge and inherit helpers lock only the source ruleset: the previous
lock of both destination and source collapses to a single
mutex_lock(&amp;src-&gt;lock).

Rename the per-layer access-mask field from access_masks to
handled_masks, naming it by the role it plays (the rights each layer
handles) rather than by its type, paralleling the struct access_masks
quiet_masks field.  Drop the now domain-only fields (hierarchy,
work_free, num_layers) from struct landlock_ruleset.

The new struct landlock_domain field in cred.h pulls in domain.h, which
includes audit.h, which previously included cred.h, forming an include
cycle.  Break it by having audit.h forward-declare the struct
landlock_cred_security and struct landlock_hierarchy it uses instead of
including cred.h.

Cc: Günther Noack &lt;gnoack@google.com&gt;
Cc: Tingmao Wang &lt;m@maowtm.org&gt;
Link: https://patch.msgid.link/20260811094338.288094-4-mic@digikod.net
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Switch all domain users to the new struct landlock_domain type
introduced by a previous commit, eliminating the conflation between
mutable rulesets and immutable domains. landlock_merge_ruleset() now
returns and allocates a struct landlock_domain, and the merge and
inherit helpers move next to it; the former static insert_rule() is
exported as landlock_store_rule() for its new caller across the
translation-unit boundary.

The merge destination is now a private struct landlock_domain still
under construction (owned by the calling thread, not yet shared), so the
merge and inherit helpers lock only the source ruleset: the previous
lock of both destination and source collapses to a single
mutex_lock(&amp;src-&gt;lock).

Rename the per-layer access-mask field from access_masks to
handled_masks, naming it by the role it plays (the rights each layer
handles) rather than by its type, paralleling the struct access_masks
quiet_masks field.  Drop the now domain-only fields (hierarchy,
work_free, num_layers) from struct landlock_ruleset.

The new struct landlock_domain field in cred.h pulls in domain.h, which
includes audit.h, which previously included cred.h, forming an include
cycle.  Break it by having audit.h forward-declare the struct
landlock_cred_security and struct landlock_hierarchy it uses instead of
including cred.h.

Cc: Günther Noack &lt;gnoack@google.com&gt;
Cc: Tingmao Wang &lt;m@maowtm.org&gt;
Link: https://patch.msgid.link/20260811094338.288094-4-mic@digikod.net
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>landlock: Harden sock_is_scoped() against file-less sockets</title>
<updated>2026-08-14T10:38:26+00:00</updated>
<author>
<name>Mickaël Salaün</name>
<email>mic@digikod.net</email>
</author>
<published>2026-07-03T15:27:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=07dca8ef89fc92b89ce36d9727547b10d8e840d6'/>
<id>07dca8ef89fc92b89ce36d9727547b10d8e840d6</id>
<content type='text'>
sock_is_scoped() dereferences other-&gt;sk_socket-&gt;file-&gt;f_cred to read the
peer's Landlock domain when evaluating
LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET, without first checking that the
peer has a backing socket and file.  hook_unix_find() performs the same
dereference for LANDLOCK_ACCESS_FS_RESOLVE_UNIX and does guard it.
Guard it here too and treat a peer with no backing file, such as a
kernel socket created by sock_create_kern(), as unscoped.

This is defensive hardening, not a fix for a reachable bug.  The
unix_stream_connect() and unix_may_send() hooks run with the peer held
under unix_state_lock() and only after the AF_UNIX core has excluded
SOCK_DEAD, and no in-tree code binds a file-less AF_UNIX socket to an
abstract address, so other-&gt;sk_socket-&gt;file is always valid at these
call sites today.

Cc: Günther Noack &lt;gnoack@google.com&gt;
Link: https://patch.msgid.link/20260703152750.2022878-1-mic@digikod.net
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
sock_is_scoped() dereferences other-&gt;sk_socket-&gt;file-&gt;f_cred to read the
peer's Landlock domain when evaluating
LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET, without first checking that the
peer has a backing socket and file.  hook_unix_find() performs the same
dereference for LANDLOCK_ACCESS_FS_RESOLVE_UNIX and does guard it.
Guard it here too and treat a peer with no backing file, such as a
kernel socket created by sock_create_kern(), as unscoped.

This is defensive hardening, not a fix for a reachable bug.  The
unix_stream_connect() and unix_may_send() hooks run with the peer held
under unix_state_lock() and only after the AF_UNIX core has excluded
SOCK_DEAD, and no in-tree code binds a file-less AF_UNIX socket to an
abstract address, so other-&gt;sk_socket-&gt;file is always valid at these
call sites today.

Cc: Günther Noack &lt;gnoack@google.com&gt;
Link: https://patch.msgid.link/20260703152750.2022878-1-mic@digikod.net
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>landlock: Update formatting</title>
<updated>2026-07-10T10:59:10+00:00</updated>
<author>
<name>Mickaël Salaün</name>
<email>mic@digikod.net</email>
</author>
<published>2026-07-08T11:06:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=97c0e344e03818dbf3116e77d3d7fe81f1fbe795'/>
<id>97c0e344e03818dbf3116e77d3d7fe81f1fbe795</id>
<content type='text'>
Following commit 99df2a8eba34 ("clang-format: fix formatting of guard()
and scoped_guard() statements"), update scoped_guard() formatting.
Also, see the related fix [1].

Cc: Günther Noack &lt;gnoack@google.com&gt;
Cc: Miguel Ojeda &lt;ojeda@kernel.org&gt;
Link: https://lore.kernel.org/r/20260708105713.2073335-1-mic@digikod.net [1]
Link: https://patch.msgid.link/20260708110635.2083515-1-mic@digikod.net
Reviewed-by: Günther Noack &lt;gnoack@google.com&gt;
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Following commit 99df2a8eba34 ("clang-format: fix formatting of guard()
and scoped_guard() statements"), update scoped_guard() formatting.
Also, see the related fix [1].

Cc: Günther Noack &lt;gnoack@google.com&gt;
Cc: Miguel Ojeda &lt;ojeda@kernel.org&gt;
Link: https://lore.kernel.org/r/20260708105713.2073335-1-mic@digikod.net [1]
Link: https://patch.msgid.link/20260708110635.2083515-1-mic@digikod.net
Reviewed-by: Günther Noack &lt;gnoack@google.com&gt;
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>landlock: Fix LANDLOCK_SCOPE_SIGNAL bypass on the SIGIO path</title>
<updated>2026-06-13T21:14:59+00:00</updated>
<author>
<name>Bryam Vargas</name>
<email>hexlabsecurity@proton.me</email>
</author>
<published>2026-06-04T23:16:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=4b80320ca7ed03d6e683f95b6066565dc97b9f92'/>
<id>4b80320ca7ed03d6e683f95b6066565dc97b9f92</id>
<content type='text'>
LANDLOCK_SCOPE_SIGNAL must prevent a sandboxed process from signaling
processes outside its Landlock domain.  It can be bypassed through the
asynchronous SIGIO delivery path.

A sandboxed process that owns any file or socket can arm it with
fcntl(fd, F_SETOWN, -pgid), fcntl(fd, F_SETSIG, SIGKILL) and O_ASYNC, so
that an I/O event makes the kernel deliver the chosen signal to the
whole process group.  As the head of its process group's task list (the
default position right after fork()) that group can also hold the
non-sandboxed process that launched it, e.g. a supervisor or a security
monitor.  The sandbox can thus kill or signal the processes
LANDLOCK_SCOPE_SIGNAL is meant to protect from it.

The scope is enforced in hook_file_send_sigiotask() against the Landlock
domain recorded at F_SETOWN time, not the live domain of the sender.
control_current_fowner() decides whether to record that domain and skips
recording it when the fowner target is in the caller's thread group,
which is safe only for a single-task target (PIDTYPE_PID, PIDTYPE_TGID).
For a process group (PIDTYPE_PGID) pid_task() returns only one member;
recording is skipped whenever that member shares the caller's thread
group, and hook_file_send_sigiotask() then lets the signal fan out to
the whole group unchecked.

Record the domain for every non single-process target so the scope is
enforced against each group member at delivery time.

That recording is necessary but not sufficient on its own: the kernel
signals a process group through its members' thread-group leaders, and
the leader of the registrant's own process can carry a different
Landlock domain than the sibling thread that armed the owner.
domain_is_scoped() would then deny that leader, even though commit
18eb75f3af40 ("landlock: Always allow signals between threads of the
same process") requires same-process delivery to be allowed.
hook_task_kill() avoids this by evaluating same_thread_group() live, per
recipient; the SIGIO path instead delegates the whole decision to a
single registration-time check, which a process-group fan-out cannot
honor.

So also record the registrant's thread group next to its domain and
exempt it at delivery: hook_file_send_sigiotask() allows the signal
whenever the recipient belongs to the registrant's own process,
restoring the same-process guarantee while keeping out-of-domain group
members blocked.  The direct kill() path (hook_task_kill) already
evaluates the live domain and is unaffected.

Fixes: 18eb75f3af40 ("landlock: Always allow signals between threads of the same process")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas &lt;hexlabsecurity@proton.me&gt;
Reviewed-by: Günther Noack &lt;gnoack3000@gmail.com&gt;
Link: https://patch.msgid.link/56bffc24f3d0d08b45a686a48e99766b0a0821fa.1780614610.git.hexlabsecurity@proton.me
[mic: Check pid_type earlier and improve comment, fix commit message,
fix comment formatting]
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
LANDLOCK_SCOPE_SIGNAL must prevent a sandboxed process from signaling
processes outside its Landlock domain.  It can be bypassed through the
asynchronous SIGIO delivery path.

A sandboxed process that owns any file or socket can arm it with
fcntl(fd, F_SETOWN, -pgid), fcntl(fd, F_SETSIG, SIGKILL) and O_ASYNC, so
that an I/O event makes the kernel deliver the chosen signal to the
whole process group.  As the head of its process group's task list (the
default position right after fork()) that group can also hold the
non-sandboxed process that launched it, e.g. a supervisor or a security
monitor.  The sandbox can thus kill or signal the processes
LANDLOCK_SCOPE_SIGNAL is meant to protect from it.

The scope is enforced in hook_file_send_sigiotask() against the Landlock
domain recorded at F_SETOWN time, not the live domain of the sender.
control_current_fowner() decides whether to record that domain and skips
recording it when the fowner target is in the caller's thread group,
which is safe only for a single-task target (PIDTYPE_PID, PIDTYPE_TGID).
For a process group (PIDTYPE_PGID) pid_task() returns only one member;
recording is skipped whenever that member shares the caller's thread
group, and hook_file_send_sigiotask() then lets the signal fan out to
the whole group unchecked.

Record the domain for every non single-process target so the scope is
enforced against each group member at delivery time.

That recording is necessary but not sufficient on its own: the kernel
signals a process group through its members' thread-group leaders, and
the leader of the registrant's own process can carry a different
Landlock domain than the sibling thread that armed the owner.
domain_is_scoped() would then deny that leader, even though commit
18eb75f3af40 ("landlock: Always allow signals between threads of the
same process") requires same-process delivery to be allowed.
hook_task_kill() avoids this by evaluating same_thread_group() live, per
recipient; the SIGIO path instead delegates the whole decision to a
single registration-time check, which a process-group fan-out cannot
honor.

So also record the registrant's thread group next to its domain and
exempt it at delivery: hook_file_send_sigiotask() allows the signal
whenever the recipient belongs to the registrant's own process,
restoring the same-process guarantee while keeping out-of-domain group
members blocked.  The direct kill() path (hook_task_kill) already
evaluates the live domain and is unaffected.

Fixes: 18eb75f3af40 ("landlock: Always allow signals between threads of the same process")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas &lt;hexlabsecurity@proton.me&gt;
Reviewed-by: Günther Noack &lt;gnoack3000@gmail.com&gt;
Link: https://patch.msgid.link/56bffc24f3d0d08b45a686a48e99766b0a0821fa.1780614610.git.hexlabsecurity@proton.me
[mic: Check pid_type earlier and improve comment, fix commit message,
fix comment formatting]
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>landlock: Clarify BUILD_BUG_ON check in scoping logic</title>
<updated>2026-04-07T16:51:07+00:00</updated>
<author>
<name>Günther Noack</name>
<email>gnoack3000@gmail.com</email>
</author>
<published>2026-03-27T16:48:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=a46e32db1fb7acac49a35773345d4bcf343847f5'/>
<id>a46e32db1fb7acac49a35773345d4bcf343847f5</id>
<content type='text'>
The BUILD_BUG_ON check in domain_is_scoped() and
unmask_scoped_access() should check that the loop that counts down
client_layer finishes.  We therefore check that the numbers
LANDLOCK_MAX_NUM_LAYERS-1 and -1 are both representable by that
integer.  If they are representable, the numbers in between are
representable too, and the loop finishes.

Signed-off-by: Günther Noack &lt;gnoack3000@gmail.com&gt;
Link: https://lore.kernel.org/r/20260327164838.38231-6-gnoack3000@gmail.com
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The BUILD_BUG_ON check in domain_is_scoped() and
unmask_scoped_access() should check that the loop that counts down
client_layer finishes.  We therefore check that the numbers
LANDLOCK_MAX_NUM_LAYERS-1 and -1 are both representable by that
integer.  If they are representable, the numbers in between are
representable too, and the loop finishes.

Signed-off-by: Günther Noack &lt;gnoack3000@gmail.com&gt;
Link: https://lore.kernel.org/r/20260327164838.38231-6-gnoack3000@gmail.com
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>landlock: Improve kernel-doc "Return:" section consistency</title>
<updated>2026-04-07T16:51:04+00:00</updated>
<author>
<name>Mickaël Salaün</name>
<email>mic@digikod.net</email>
</author>
<published>2026-03-04T19:31:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=fa20aeb95d72da9dd78a3c9b24e996b5d9219888'/>
<id>fa20aeb95d72da9dd78a3c9b24e996b5d9219888</id>
<content type='text'>
The canonical kernel-doc form is "Return:" (singular, without trailing
"s").  Normalize all existing "Returns:" occurrences across the Landlock
source tree to the canonical form.

Also fix capitalization for consistency.  Balance descriptions to
describe all possible returned values.

Consolidate bullet-point return descriptions into inline text for
functions with simple two-value or three-value returns for consistency.

Cc: Günther Noack &lt;gnoack@google.com&gt;
Reviewed-by: Günther Noack &lt;gnoack3000@gmail.com&gt;
Link: https://lore.kernel.org/r/20260304193134.250495-3-mic@digikod.net
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The canonical kernel-doc form is "Return:" (singular, without trailing
"s").  Normalize all existing "Returns:" occurrences across the Landlock
source tree to the canonical form.

Also fix capitalization for consistency.  Balance descriptions to
describe all possible returned values.

Consolidate bullet-point return descriptions into inline text for
functions with simple two-value or three-value returns for consistency.

Cc: Günther Noack &lt;gnoack@google.com&gt;
Reviewed-by: Günther Noack &lt;gnoack3000@gmail.com&gt;
Link: https://lore.kernel.org/r/20260304193134.250495-3-mic@digikod.net
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>landlock: Add missing kernel-doc "Return:" sections</title>
<updated>2026-04-07T16:51:03+00:00</updated>
<author>
<name>Mickaël Salaün</name>
<email>mic@digikod.net</email>
</author>
<published>2026-03-04T19:31:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=e89dea254dce44c629d98639c05fe5ca7add7241'/>
<id>e89dea254dce44c629d98639c05fe5ca7add7241</id>
<content type='text'>
The kernel-doc -Wreturn check warns about functions with documentation
comments that lack a "Return:" section.  Add "Return:" documentation to
all functions missing it so that kernel-doc -Wreturn passes cleanly.

Convert existing function descriptions into a formal "Return:" section.
Also fix the inaccurate return documentation for
landlock_merge_ruleset() which claimed to return @parent directly, and
document the previously missing ERR_PTR() error return path.  Document
the ABI version and errata return paths for landlock_create_ruleset()
which were previously only implied by the prose.

Cc: Günther Noack &lt;gnoack@google.com&gt;
Reviewed-by: Günther Noack &lt;gnoack3000@gmail.com&gt;
Link: https://lore.kernel.org/r/20260304193134.250495-2-mic@digikod.net
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The kernel-doc -Wreturn check warns about functions with documentation
comments that lack a "Return:" section.  Add "Return:" documentation to
all functions missing it so that kernel-doc -Wreturn passes cleanly.

Convert existing function descriptions into a formal "Return:" section.
Also fix the inaccurate return documentation for
landlock_merge_ruleset() which claimed to return @parent directly, and
document the previously missing ERR_PTR() error return path.  Document
the ABI version and errata return paths for landlock_create_ruleset()
which were previously only implied by the prose.

Cc: Günther Noack &lt;gnoack@google.com&gt;
Reviewed-by: Günther Noack &lt;gnoack3000@gmail.com&gt;
Link: https://lore.kernel.org/r/20260304193134.250495-2-mic@digikod.net
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>landlock: Improve the comment for domain_is_scoped</title>
<updated>2025-12-29T15:19:39+00:00</updated>
<author>
<name>Tingmao Wang</name>
<email>m@maowtm.org</email>
</author>
<published>2025-12-28T01:27:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=ef4536f15224418b327a7b5d5cae07dab042760f'/>
<id>ef4536f15224418b327a7b5d5cae07dab042760f</id>
<content type='text'>
Currently it is not obvious what "scoped" mean, and the fact that the
function returns true when access should be denied is slightly surprising
and in need of documentation.

Cc: Tahera Fahimi &lt;fahimitahera@gmail.com&gt;
Signed-off-by: Tingmao Wang &lt;m@maowtm.org&gt;
Link: https://lore.kernel.org/r/06393bc18aee5bc278df5ef31c64a05b742ebc10.1766885035.git.m@maowtm.org
[mic: Fix formatting and improve consistency]
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Currently it is not obvious what "scoped" mean, and the fact that the
function returns true when access should be denied is slightly surprising
and in need of documentation.

Cc: Tahera Fahimi &lt;fahimitahera@gmail.com&gt;
Signed-off-by: Tingmao Wang &lt;m@maowtm.org&gt;
Link: https://lore.kernel.org/r/06393bc18aee5bc278df5ef31c64a05b742ebc10.1766885035.git.m@maowtm.org
[mic: Fix formatting and improve consistency]
Signed-off-by: Mickaël Salaün &lt;mic@digikod.net&gt;
</pre>
</div>
</content>
</entry>
</feed>
