* Re: [PATCH RFC] ima: Fallback to a ctime guard without i_version updates
From: Frederick Lawler @ 2026-01-05 23:09 UTC (permalink / raw)
To: Mimi Zohar
Cc: Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Paul Moore,
James Morris, Serge E. Hallyn, Darrick J. Wong, Christian Brauner,
Josef Bacik, Jeff Layton, linux-kernel, linux-integrity,
linux-security-module, kernel-team
In-Reply-To: <4a4778ff395e533cad86ff3ffbf0ba90c3eb8798.camel@linux.ibm.com>
Hi Mimi,
On Mon, Jan 05, 2026 at 05:15:15PM -0500, Mimi Zohar wrote:
> On Mon, 2025-12-29 at 11:52 -0600, Frederick Lawler wrote:
> > Since commit 1cf7e834a6fb ("xfs: switch to multigrain timestamps"), IMA
> > is no longer able to correctly track inode.i_version due to the struct
> > kstat.change_cookie no longer containing an updated i_version.
> >
> > Introduce a fallback mechanism for IMA that instead tracks a
> > integrity_ctime_guard() in absence of or outdated i_version
> > for stacked file systems.
>
> Thanks, Frederick.
>
> Instead of using the new function name integrity_ctime_guard() to describe the
> change, please describe the change in words. Perhaps something like: rely on
> the inode's ctime to detect a file data or metadata change.
>
Sure thing, I'll change for the v1.
> The purpose of generating a ctime guard value, as opposed to using the tv_sec
> and tv_nsec, I assume is to minimize the amount of memory being saved in the
> iint.
This was Jeff's suggestion. It does serve the purpose on saving
some memory, but also has some value in the event nsec or sec is zero'd.
It just needs to be different enough from the last cache'd evaluation.
>
> >
> > EVM is left alone since it mostly cares about the backing inode.
> >
> > Link: https://lore.kernel.org/all/aTspr4_h9IU4EyrR@CMGLRV3
> > Fixes: 1cf7e834a6fb ("xfs: switch to multigrain timestamps")
> > Suggested-by: Jeff Layton <jlayton@kernel.org>
> > Signed-off-by: Frederick Lawler <fred@cloudflare.com>
> > ---
> > The motivation behind this was that file systems that use the
> > cookie to set the i_version for stacked file systems may still do so.
> > Then add in the ctime_guard as a fallback if there's a detected change.
> > The assumption is that the ctime will be different if the i_version is
> > different anyway for non-stacked file systems.
>
> Agreed. This patch inverts the i_version test to return immediately if the
> i_version hasn't changed and then checks the ctime guard value. Is the ctime
> guard value test simply a performance improvement?
>
Kinda. The thought was to make already-audited files that have an
unchanged i_version since last audit succeed early.
Stacking tempfs on XFS for instance, would incur the stat cost each
evaluation, since the cookie that used to set the i_version on
evaluation with XFS on 6.12, is now always setting it to zero since 6.13.
> >
> > I'm not too pleased with passing in struct file* to
> > integrity_inode_attrs_changed() since EVM doesn't currently use
> > that for now, but I couldn't come up with another idea to get the
> > stat without coming up with a new stat function to accommodate just
> > the file path, fully separate out IMA/EVM checks, or lastly add stacked
> > file system support to EVM (which doesn't make much sense to me
> > at the moment).
> >
> > I plan on adding in self test infrastructure for the v1, but I would
> > like to get some early feedback on the approach first.
>
> I really appreciate your adding a self test.
>
I was poking around last week at some testing platforms, and instead of
adding to kernel sefltests & setup a VM etc..., to instead add to
Linux Test Project (LTP) if that's fine?
In any case, I can add my test snippet to v1, so you have something
to review with the patch. That snippet works the same on 6.12 as it
does on 6.19 with this patch.
> thanks,
>
> Mimi
^ permalink raw reply
* Re: [PATCH RFC] ima: Fallback to a ctime guard without i_version updates
From: Mimi Zohar @ 2026-01-05 22:15 UTC (permalink / raw)
To: Frederick Lawler, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
Paul Moore, James Morris, Serge E. Hallyn, Darrick J. Wong,
Christian Brauner, Josef Bacik, Jeff Layton
Cc: linux-kernel, linux-integrity, linux-security-module, kernel-team
In-Reply-To: <20251229-xfs-ima-fixup-v1-1-6a717c939f7c@cloudflare.com>
On Mon, 2025-12-29 at 11:52 -0600, Frederick Lawler wrote:
> Since commit 1cf7e834a6fb ("xfs: switch to multigrain timestamps"), IMA
> is no longer able to correctly track inode.i_version due to the struct
> kstat.change_cookie no longer containing an updated i_version.
>
> Introduce a fallback mechanism for IMA that instead tracks a
> integrity_ctime_guard() in absence of or outdated i_version
> for stacked file systems.
Thanks, Frederick.
Instead of using the new function name integrity_ctime_guard() to describe the
change, please describe the change in words. Perhaps something like: rely on
the inode's ctime to detect a file data or metadata change.
The purpose of generating a ctime guard value, as opposed to using the tv_sec
and tv_nsec, I assume is to minimize the amount of memory being saved in the
iint.
>
> EVM is left alone since it mostly cares about the backing inode.
>
> Link: https://lore.kernel.org/all/aTspr4_h9IU4EyrR@CMGLRV3
> Fixes: 1cf7e834a6fb ("xfs: switch to multigrain timestamps")
> Suggested-by: Jeff Layton <jlayton@kernel.org>
> Signed-off-by: Frederick Lawler <fred@cloudflare.com>
> ---
> The motivation behind this was that file systems that use the
> cookie to set the i_version for stacked file systems may still do so.
> Then add in the ctime_guard as a fallback if there's a detected change.
> The assumption is that the ctime will be different if the i_version is
> different anyway for non-stacked file systems.
Agreed. This patch inverts the i_version test to return immediately if the
i_version hasn't changed and then checks the ctime guard value. Is the ctime
guard value test simply a performance improvement?
>
> I'm not too pleased with passing in struct file* to
> integrity_inode_attrs_changed() since EVM doesn't currently use
> that for now, but I couldn't come up with another idea to get the
> stat without coming up with a new stat function to accommodate just
> the file path, fully separate out IMA/EVM checks, or lastly add stacked
> file system support to EVM (which doesn't make much sense to me
> at the moment).
>
> I plan on adding in self test infrastructure for the v1, but I would
> like to get some early feedback on the approach first.
I really appreciate your adding a self test.
thanks,
Mimi
^ permalink raw reply
* Re: [RFC PATCH 0/1] lsm: Add hook unix_path_connect
From: Justin Suess @ 2026-01-05 16:04 UTC (permalink / raw)
To: Günther Noack, Kuniyuki Iwashima
Cc: Paul Moore, James Morris, Serge E . Hallyn, Simon Horman,
Mickaël Salaün, linux-security-module, Tingmao Wang,
netdev
In-Reply-To: <aVuaqij9nXhLfAvN@google.com>
On 1/5/26 06:04, Günther Noack wrote:
> Hello!
>
> On Sun, Jan 04, 2026 at 11:46:46PM -0800, Kuniyuki Iwashima wrote:
>> On Wed, Dec 31, 2025 at 1:33 PM Justin Suess <utilityemal77@gmail.com> wrote:
>>> Motivation
>>> ---
>>>
>>> For AF_UNIX sockets bound to a filesystem path (aka named sockets), one
>>> identifying object from a policy perspective is the path passed to
>>> connect(2). However, this operation currently restricts LSMs that rely
>>> on VFS-based mediation, because the pathname resolved during connect()
>>> is not preserved in a form visible to existing hooks before connection
>>> establishment.
>> Why can't LSM use unix_sk(other)->path in security_unix_stream_connect()
>> and security_unix_may_send() ?
> Thanks for bringing it up!
>
> That path is set by the process that acts as the listening side for
> the socket. The listening and the connecting process might not live
> in the same mount namespace, and in that case, it would not match the
> path which is passed by the client in the struct sockaddr_un.
Agreed. For the unix_sk(other)->path method you described to work, it requires the
programs to be in the same mount namespace.
Doing it this way would make it impossible for landlock to restrict sockets mounted into a container,
and would be very confusing behavior for users to deal with, which is exactly the kind of stuff landlock avoids.
Does anyone have any thoughts on ignoring SOCK_COREDUMP? I think ignoring it for this check is correct.
>
> For more details, see
> https://lore.kernel.org/all/20260101134102.25938-1-gnoack3000@gmail.com/
> and
> https://github.com/landlock-lsm/linux/issues/36#issuecomment-2950632277
>
> Justin: Maybe we could add that reasoning to the cover letter in the
> next version of the patch?
>
> –Günther
Will do. It's about ready to go, I may resend it today if I have time.
^ permalink raw reply
* Re: [PATCH v2 00/27] Allow inlining C helpers into Rust when using LTO
From: Boqun Feng @ 2026-01-05 15:41 UTC (permalink / raw)
To: Alice Ryhl
Cc: rust-for-linux, linux-kernel, Gary Guo, Peter Zijlstra,
Elle Rhumsaa, Andreas Hindborg, linux-block, FUJITA Tomonori,
Miguel Ojeda, Michael Turquette, Stephen Boyd, linux-clk,
Benno Lossin, Danilo Krummrich, Thomas Gleixner, Paul Moore,
Serge Hallyn, linux-security-module, Josh Poimboeuf, Jason Baron,
Steven Rostedt, Ard Biesheuvel, Andrew Ballance, Andrew Morton,
Liam R. Howlett, maple-tree, linux-mm, Lorenzo Stoakes,
Uladzislau Rezki, Vitaly Wool, Rob Herring, devicetree,
Daniel Almeida, Michal Wilczynski, linux-pwm, Paul E. McKenney,
rcu, Will Deacon, Fiona Behrens, Greg Kroah-Hartman,
Vlastimil Babka, Christoph Lameter, David Rientjes, Ingo Molnar,
Waiman Long, Mitchell Levy, Frederic Weisbecker, Lyude Paul,
Anna-Maria Behnsen, John Stultz, linux-usb, Tejun Heo,
Lai Jiangshan, Matthew Wilcox, Tamir Duberstein, linux-fsdevel
In-Reply-To: <20260105-define-rust-helper-v2-0-51da5f454a67@google.com>
On Mon, Jan 05, 2026 at 12:42:13PM +0000, Alice Ryhl wrote:
> This patch series adds __rust_helper to every single rust helper. The
> patches do not depend on each other, so maintainers please go ahead and
> pick up any patches relevant to your subsystem! Or provide your Acked-by
> so that Miguel can pick them up.
>
I queued the following into rust-sync:
rust: barrier: add __rust_helper to helpers
rust: blk: add __rust_helper to helpers
rust: completion: add __rust_helper to helpers
rust: cpu: add __rust_helper to helpers
rust: processor: add __rust_helper to helpers
rust: rcu: add __rust_helper to helpers
rust: refcount: add __rust_helper to helpers
rust: sync: add __rust_helper to helpers
rust: task: add __rust_helper to helpers
rust: time: add __rust_helper to helpers
rust: wait: add __rust_helper to helpers
Thanks!
Regards,
Boqun
> These changes were generated by adding __rust_helper and running
> ClangFormat. Unrelated formatting changes were removed manually.
>
[...]
^ permalink raw reply
* [PATCH v2 18/27] rust: security: add __rust_helper to helpers
From: Alice Ryhl @ 2026-01-05 12:42 UTC (permalink / raw)
To: rust-for-linux
Cc: linux-kernel, Alice Ryhl, Boqun Feng, Gary Guo, Paul Moore,
Greg Kroah-Hartman, linux-security-module
In-Reply-To: <20260105-define-rust-helper-v2-0-51da5f454a67@google.com>
This is needed to inline these helpers into Rust code.
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
Cc: Paul Moore <paul@paul-moore.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-security-module@vger.kernel.org
---
rust/helpers/security.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/rust/helpers/security.c b/rust/helpers/security.c
index ca22da09548dfed95a83168ed09263e75cf08fd2..8d0a25fcf931ac6540a986aa10187c345614fc9e 100644
--- a/rust/helpers/security.c
+++ b/rust/helpers/security.c
@@ -3,41 +3,45 @@
#include <linux/security.h>
#ifndef CONFIG_SECURITY
-void rust_helper_security_cred_getsecid(const struct cred *c, u32 *secid)
+__rust_helper void rust_helper_security_cred_getsecid(const struct cred *c,
+ u32 *secid)
{
security_cred_getsecid(c, secid);
}
-int rust_helper_security_secid_to_secctx(u32 secid, struct lsm_context *cp)
+__rust_helper int rust_helper_security_secid_to_secctx(u32 secid,
+ struct lsm_context *cp)
{
return security_secid_to_secctx(secid, cp);
}
-void rust_helper_security_release_secctx(struct lsm_context *cp)
+__rust_helper void rust_helper_security_release_secctx(struct lsm_context *cp)
{
security_release_secctx(cp);
}
-int rust_helper_security_binder_set_context_mgr(const struct cred *mgr)
+__rust_helper int
+rust_helper_security_binder_set_context_mgr(const struct cred *mgr)
{
return security_binder_set_context_mgr(mgr);
}
-int rust_helper_security_binder_transaction(const struct cred *from,
- const struct cred *to)
+__rust_helper int
+rust_helper_security_binder_transaction(const struct cred *from,
+ const struct cred *to)
{
return security_binder_transaction(from, to);
}
-int rust_helper_security_binder_transfer_binder(const struct cred *from,
- const struct cred *to)
+__rust_helper int
+rust_helper_security_binder_transfer_binder(const struct cred *from,
+ const struct cred *to)
{
return security_binder_transfer_binder(from, to);
}
-int rust_helper_security_binder_transfer_file(const struct cred *from,
- const struct cred *to,
- const struct file *file)
+__rust_helper int rust_helper_security_binder_transfer_file(
+ const struct cred *from, const struct cred *to, const struct file *file)
{
return security_binder_transfer_file(from, to, file);
}
--
2.52.0.351.gbe84eed79e-goog
^ permalink raw reply related
* [PATCH v2 07/27] rust: cred: add __rust_helper to helpers
From: Alice Ryhl @ 2026-01-05 12:42 UTC (permalink / raw)
To: rust-for-linux
Cc: linux-kernel, Alice Ryhl, Boqun Feng, Gary Guo, Paul Moore,
Serge Hallyn, linux-security-module
In-Reply-To: <20260105-define-rust-helper-v2-0-51da5f454a67@google.com>
This is needed to inline these helpers into Rust code.
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
Cc: Paul Moore <paul@paul-moore.com>
Cc: Serge Hallyn <sergeh@kernel.org>
Cc: linux-security-module@vger.kernel.org
---
rust/helpers/cred.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/rust/helpers/cred.c b/rust/helpers/cred.c
index fde7ae20cdd19f04ac5f28808586c65de6b72f09..a56a7b7536232733dcdc640f09f8f2537e69d75e 100644
--- a/rust/helpers/cred.c
+++ b/rust/helpers/cred.c
@@ -2,12 +2,12 @@
#include <linux/cred.h>
-const struct cred *rust_helper_get_cred(const struct cred *cred)
+__rust_helper const struct cred *rust_helper_get_cred(const struct cred *cred)
{
return get_cred(cred);
}
-void rust_helper_put_cred(const struct cred *cred)
+__rust_helper void rust_helper_put_cred(const struct cred *cred)
{
put_cred(cred);
}
--
2.52.0.351.gbe84eed79e-goog
^ permalink raw reply related
* [PATCH v2 00/27] Allow inlining C helpers into Rust when using LTO
From: Alice Ryhl @ 2026-01-05 12:42 UTC (permalink / raw)
To: rust-for-linux
Cc: linux-kernel, Alice Ryhl, Boqun Feng, Gary Guo, Peter Zijlstra,
Elle Rhumsaa, Andreas Hindborg, linux-block, FUJITA Tomonori,
Miguel Ojeda, Michael Turquette, Stephen Boyd, linux-clk,
Benno Lossin, Danilo Krummrich, Thomas Gleixner, Paul Moore,
Serge Hallyn, linux-security-module, Josh Poimboeuf, Jason Baron,
Steven Rostedt, Ard Biesheuvel, Andrew Ballance, Andrew Morton,
Liam R. Howlett, maple-tree, linux-mm, Lorenzo Stoakes,
Uladzislau Rezki, Vitaly Wool, Rob Herring, devicetree,
Daniel Almeida, Michal Wilczynski, linux-pwm, Paul E. McKenney,
rcu, Will Deacon, Fiona Behrens, Greg Kroah-Hartman,
Vlastimil Babka, Christoph Lameter, David Rientjes, Ingo Molnar,
Waiman Long, Mitchell Levy, Frederic Weisbecker, Lyude Paul,
Anna-Maria Behnsen, John Stultz, linux-usb, Tejun Heo,
Lai Jiangshan, Matthew Wilcox, Tamir Duberstein, linux-fsdevel
This patch series adds __rust_helper to every single rust helper. The
patches do not depend on each other, so maintainers please go ahead and
pick up any patches relevant to your subsystem! Or provide your Acked-by
so that Miguel can pick them up.
These changes were generated by adding __rust_helper and running
ClangFormat. Unrelated formatting changes were removed manually.
Why is __rust_helper needed?
============================
Currently, C helpers cannot be inlined into Rust even when using LTO
because LLVM detects slightly different options on the codegen units.
* LLVM doesn't want to inline functions compiled with
`-fno-delete-null-pointer-checks` with code compiled without. The C
CGUs all have this enabled and Rust CGUs don't. Inlining is okay since
this is one of the hardening features that does not change the ABI,
and we shouldn't have null pointer dereferences in these helpers.
* LLVM doesn't want to inline functions with different list of builtins. C
side has `-fno-builtin-wcslen`; `wcslen` is not a Rust builtin, so
they should be compatible, but LLVM does not perform inlining due to
attributes mismatch.
* clang and Rust doesn't have the exact target string. Clang generates
`+cmov,+cx8,+fxsr` but Rust doesn't enable them (in fact, Rust will
complain if `-Ctarget-feature=+cmov,+cx8,+fxsr` is used). x86-64
always enable these features, so they are in fact the same target
string, but LLVM doesn't understand this and so inlining is inhibited.
This can be bypassed with `--ignore-tti-inline-compatible`, but this
is a hidden option.
(This analysis was written by Gary Guo.)
How is this fixed?
==================
To fix this we need to add __always_inline to all helpers when compiling
with LTO. However, it should not be added when running bindgen as
bindgen will ignore functions marked inline. To achieve this, we are
using a #define called __rust_helper that is defined differently
depending on whether bindgen is running or not.
Note that __rust_helper is currently always #defined to nothing.
Changing it to __always_inline will happen separately in another patch
series.
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
Changes in v2:
- Pick up Reviewed-by: Boqun Feng <boqun.feng@gmail.com>, Gary Guo <gary@garyguo.net>
- Update formatting in mm and slab patches.
- Add new helpers in files uaccess, pwm, and time.
- Drop any patches that have been merged.
- Link to v1: https://lore.kernel.org/r/20251202-define-rust-helper-v1-0-a2e13cbc17a6@google.com
---
Alice Ryhl (27):
rust: barrier: add __rust_helper to helpers
rust: blk: add __rust_helper to helpers
rust: bug: add __rust_helper to helpers
rust: clk: add __rust_helper to helpers
rust: completion: add __rust_helper to helpers
rust: cpu: add __rust_helper to helpers
rust: cred: add __rust_helper to helpers
rust: err: add __rust_helper to helpers
rust: jump_label: add __rust_helper to helpers
rust: maple_tree: add __rust_helper to helpers
rust: mm: add __rust_helper to helpers
rust: of: add __rust_helper to helpers
rust: processor: add __rust_helper to helpers
rust: pwm: add __rust_helper to helpers
rust: rbtree: add __rust_helper to helpers
rust: rcu: add __rust_helper to helpers
rust: refcount: add __rust_helper to helpers
rust: security: add __rust_helper to helpers
rust: slab: add __rust_helper to helpers
rust: sync: add __rust_helper to helpers
rust: task: add __rust_helper to helpers
rust: time: add __rust_helper to helpers
rust: uaccess: add __rust_helper to helpers
rust: usb: add __rust_helper to helpers
rust: wait: add __rust_helper to helpers
rust: workqueue: add __rust_helper to helpers
rust: xarray: add __rust_helper to helpers
rust/helpers/barrier.c | 6 +++---
rust/helpers/blk.c | 4 ++--
rust/helpers/bug.c | 4 ++--
rust/helpers/build_bug.c | 2 +-
rust/helpers/clk.c | 24 +++++++++++++-----------
rust/helpers/completion.c | 2 +-
rust/helpers/cpu.c | 2 +-
rust/helpers/cred.c | 4 ++--
rust/helpers/err.c | 6 +++---
rust/helpers/jump_label.c | 2 +-
rust/helpers/maple_tree.c | 3 ++-
rust/helpers/mm.c | 20 ++++++++++----------
rust/helpers/mutex.c | 13 +++++++------
rust/helpers/of.c | 2 +-
rust/helpers/page.c | 9 +++++----
rust/helpers/processor.c | 2 +-
rust/helpers/pwm.c | 6 +++---
rust/helpers/rbtree.c | 9 +++++----
rust/helpers/rcu.c | 4 ++--
rust/helpers/refcount.c | 10 +++++-----
rust/helpers/security.c | 26 +++++++++++++++-----------
rust/helpers/signal.c | 2 +-
rust/helpers/slab.c | 4 ++--
rust/helpers/spinlock.c | 13 +++++++------
rust/helpers/sync.c | 4 ++--
rust/helpers/task.c | 24 ++++++++++++------------
rust/helpers/time.c | 14 +++++++-------
rust/helpers/uaccess.c | 10 ++++++----
rust/helpers/usb.c | 3 ++-
rust/helpers/vmalloc.c | 2 +-
rust/helpers/wait.c | 2 +-
rust/helpers/workqueue.c | 8 +++++---
rust/helpers/xarray.c | 10 +++++-----
33 files changed, 136 insertions(+), 120 deletions(-)
---
base-commit: 9ace4753a5202b02191d54e9fdf7f9e3d02b85eb
change-id: 20251202-define-rust-helper-f7b531813007
Best regards,
--
Alice Ryhl <aliceryhl@google.com>
^ permalink raw reply
* Re: [RFC PATCH 0/1] lsm: Add hook unix_path_connect
From: Günther Noack @ 2026-01-05 11:04 UTC (permalink / raw)
To: Kuniyuki Iwashima
Cc: Justin Suess, Paul Moore, James Morris, Serge E . Hallyn,
Simon Horman, Mickaël Salaün, linux-security-module,
Tingmao Wang, netdev
In-Reply-To: <CAAVpQUCF3uES6j22P1TYzgKByw+E4EqpM=+OFyqtRGStGWxH+Q@mail.gmail.com>
Hello!
On Sun, Jan 04, 2026 at 11:46:46PM -0800, Kuniyuki Iwashima wrote:
> On Wed, Dec 31, 2025 at 1:33 PM Justin Suess <utilityemal77@gmail.com> wrote:
> > Motivation
> > ---
> >
> > For AF_UNIX sockets bound to a filesystem path (aka named sockets), one
> > identifying object from a policy perspective is the path passed to
> > connect(2). However, this operation currently restricts LSMs that rely
> > on VFS-based mediation, because the pathname resolved during connect()
> > is not preserved in a form visible to existing hooks before connection
> > establishment.
>
> Why can't LSM use unix_sk(other)->path in security_unix_stream_connect()
> and security_unix_may_send() ?
Thanks for bringing it up!
That path is set by the process that acts as the listening side for
the socket. The listening and the connecting process might not live
in the same mount namespace, and in that case, it would not match the
path which is passed by the client in the struct sockaddr_un.
For more details, see
https://lore.kernel.org/all/20260101134102.25938-1-gnoack3000@gmail.com/
and
https://github.com/landlock-lsm/linux/issues/36#issuecomment-2950632277
Justin: Maybe we could add that reasoning to the cover letter in the
next version of the patch?
–Günther
^ permalink raw reply
* Re: [PATCH] KEYS: replace -EEXIST with -EBUSY
From: David Howells @ 2026-01-05 9:57 UTC (permalink / raw)
To: Daniel Gomez
Cc: dhowells, Lukas Wunner, Ignat Korchagin, Herbert Xu,
David S. Miller, Jarkko Sakkinen, Paul Moore, James Morris,
Serge E. Hallyn, Luis Chamberlain, Petr Pavlu, Sami Tolvanen,
Aaron Tomlin, Lucas De Marchi, keyrings, linux-crypto,
linux-modules, linux-kernel, linux-security-module, Daniel Gomez
In-Reply-To: <20251220-dev-module-init-eexists-keyring-v1-1-a2f23248c300@samsung.com>
Daniel Gomez <da.gomez@kernel.org> wrote:
> From: Daniel Gomez <da.gomez@samsung.com>
>
> The -EEXIST error code is reserved by the module loading infrastructure
> to indicate that a module is already loaded.
EEXIST means a file exists when you're trying to create it. Granted we abuse
that somewhat rather than add ever more error codes, but you cannot reserve it
for indicating that a module exists.
> When a module's init
> function returns -EEXIST, userspace tools like kmod interpret this as
> "module already loaded" and treat the operation as successful, returning
> 0 to the user even though the module initialization actually failed.
>
> This follows the precedent set by commit 54416fd76770 ("netfilter:
> conntrack: helper: Replace -EEXIST by -EBUSY") which fixed the same
> issue in nf_conntrack_helper_register().
>
> Affected modules:
> * pkcs8_key_parser x509_key_parser asymmetric_keys dns_resolver
> * nvme_keyring pkcs7_test_key rxrpc turris_signing_key
>
> Signed-off-by: Daniel Gomez <da.gomez@samsung.com>
Please don't. Userspace can always check /proc/modules (assuming procfs is
enabled, I suppose).
David
^ permalink raw reply
* Re: [PATCH] KEYS: replace -EEXIST with -EBUSY
From: Lukas Wunner @ 2026-01-05 9:33 UTC (permalink / raw)
To: Daniel Gomez
Cc: David Howells, Ignat Korchagin, Herbert Xu, David S. Miller,
Jarkko Sakkinen, Paul Moore, James Morris, Serge E. Hallyn,
Luis Chamberlain, Petr Pavlu, Sami Tolvanen, Aaron Tomlin,
Lucas De Marchi, keyrings, linux-crypto, linux-modules,
linux-kernel, linux-security-module, Daniel Gomez
In-Reply-To: <20251220-dev-module-init-eexists-keyring-v1-1-a2f23248c300@samsung.com>
On Sat, Dec 20, 2025 at 04:50:31AM +0100, Daniel Gomez wrote:
> The -EEXIST error code is reserved by the module loading infrastructure
> to indicate that a module is already loaded. When a module's init
> function returns -EEXIST, userspace tools like kmod interpret this as
> "module already loaded" and treat the operation as successful, returning
> 0 to the user even though the module initialization actually failed.
>
> This follows the precedent set by commit 54416fd76770 ("netfilter:
> conntrack: helper: Replace -EEXIST by -EBUSY") which fixed the same
> issue in nf_conntrack_helper_register().
>
> Affected modules:
> * pkcs8_key_parser x509_key_parser asymmetric_keys dns_resolver
> * nvme_keyring pkcs7_test_key rxrpc turris_signing_key
For the record, GregKH summarily rejected this approach:
https://lore.kernel.org/r/2025122212-fiction-setback-ede5@gregkh/
Thanks,
Lukas
^ permalink raw reply
* Re: [PATCH v2 00/17] tee: Use bus callbacks instead of driver callbacks
From: Jens Wiklander @ 2026-01-05 9:16 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Uwe Kleine-König, Jonathan Corbet, Sumit Garg,
Olivia Mackall, Herbert Xu, Clément Léger,
Ard Biesheuvel, Maxime Coquelin, Alexandre Torgue, Sumit Garg,
Ilias Apalodimas, Jan Kiszka, Sudeep Holla, Christophe JAILLET,
Rafał Miłecki, Michael Chan, Pavan Chebbi,
James Bottomley, Jarkko Sakkinen, Mimi Zohar, David Howells,
Paul Moore, James Morris, Serge E. Hallyn, Peter Huewe, op-tee,
linux-kernel, linux-doc, linux-crypto, linux-rtc, linux-efi,
linux-stm32, linux-arm-kernel, Cristian Marussi, arm-scmi,
linux-mips, netdev, linux-integrity, keyrings,
linux-security-module, Jason Gunthorpe
In-Reply-To: <CAHUa44GpW5aO26GDyL9RZub9vVYvVcJ7etwO0yXBN_mUi0W4AA@mail.gmail.com>
Hi,
On Thu, Dec 18, 2025 at 5:29 PM Jens Wiklander
<jens.wiklander@linaro.org> wrote:
>
> On Thu, Dec 18, 2025 at 2:53 PM Alexandre Belloni
> <alexandre.belloni@bootlin.com> wrote:
> >
> > On 18/12/2025 08:21:27+0100, Jens Wiklander wrote:
> > > Hi,
> > >
> > > On Mon, Dec 15, 2025 at 3:17 PM Uwe Kleine-König
> > > <u.kleine-koenig@baylibre.com> wrote:
> > > >
> > > > Hello,
> > > >
> > > > the objective of this series is to make tee driver stop using callbacks
> > > > in struct device_driver. These were superseded by bus methods in 2006
> > > > (commit 594c8281f905 ("[PATCH] Add bus_type probe, remove, shutdown
> > > > methods.")) but nobody cared to convert all subsystems accordingly.
> > > >
> > > > Here the tee drivers are converted. The first commit is somewhat
> > > > unrelated, but simplifies the conversion (and the drivers). It
> > > > introduces driver registration helpers that care about setting the bus
> > > > and owner. (The latter is missing in all drivers, so by using these
> > > > helpers the drivers become more correct.)
> > > >
> > > > v1 of this series is available at
> > > > https://lore.kernel.org/all/cover.1765472125.git.u.kleine-koenig@baylibre.com
> > > >
> > > > Changes since v1:
> > > >
> > > > - rebase to v6.19-rc1 (no conflicts)
> > > > - add tags received so far
> > > > - fix whitespace issues pointed out by Sumit Garg
> > > > - fix shutdown callback to shutdown and not remove
> > > >
> > > > As already noted in v1's cover letter, this series should go in during a
> > > > single merge window as there are runtime warnings when the series is
> > > > only applied partially. Sumit Garg suggested to apply the whole series
> > > > via Jens Wiklander's tree.
> > > > If this is done the dependencies in this series are honored, in case the
> > > > plan changes: Patches #4 - #17 depend on the first two.
> > > >
> > > > Note this series is only build tested.
> > > >
> > > > Uwe Kleine-König (17):
> > > > tee: Add some helpers to reduce boilerplate for tee client drivers
> > > > tee: Add probe, remove and shutdown bus callbacks to tee_client_driver
> > > > tee: Adapt documentation to cover recent additions
> > > > hwrng: optee - Make use of module_tee_client_driver()
> > > > hwrng: optee - Make use of tee bus methods
> > > > rtc: optee: Migrate to use tee specific driver registration function
> > > > rtc: optee: Make use of tee bus methods
> > > > efi: stmm: Make use of module_tee_client_driver()
> > > > efi: stmm: Make use of tee bus methods
> > > > firmware: arm_scmi: optee: Make use of module_tee_client_driver()
> > > > firmware: arm_scmi: Make use of tee bus methods
> > > > firmware: tee_bnxt: Make use of module_tee_client_driver()
> > > > firmware: tee_bnxt: Make use of tee bus methods
> > > > KEYS: trusted: Migrate to use tee specific driver registration
> > > > function
> > > > KEYS: trusted: Make use of tee bus methods
> > > > tpm/tpm_ftpm_tee: Make use of tee specific driver registration
> > > > tpm/tpm_ftpm_tee: Make use of tee bus methods
> > > >
> > > > Documentation/driver-api/tee.rst | 18 +----
> > > > drivers/char/hw_random/optee-rng.c | 26 ++----
> > > > drivers/char/tpm/tpm_ftpm_tee.c | 31 +++++---
> > > > drivers/firmware/arm_scmi/transports/optee.c | 32 +++-----
> > > > drivers/firmware/broadcom/tee_bnxt_fw.c | 30 ++-----
> > > > drivers/firmware/efi/stmm/tee_stmm_efi.c | 25 ++----
> > > > drivers/rtc/rtc-optee.c | 27 ++-----
> > > > drivers/tee/tee_core.c | 84 ++++++++++++++++++++
> > > > include/linux/tee_drv.h | 12 +++
> > > > security/keys/trusted-keys/trusted_tee.c | 17 ++--
> > > > 10 files changed, 164 insertions(+), 138 deletions(-)
> > > >
> > > > base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
> > > > --
> > > > 2.47.3
> > > >
> > >
> > > Thank you for the nice cleanup, Uwe.
> > >
> > > I've applied patch 1-3 to the branch tee_bus_callback_for_6.20 in my
> > > tree at https://git.kernel.org/pub/scm/linux/kernel/git/jenswi/linux-tee.git/
> > >
> > > The branch is based on v6.19-rc1, and I'll try to keep it stable for
> > > others to depend on, if needed. Let's see if we can agree on taking
> > > the remaining patches via that branch.
> >
> > 6 and 7 can go through your branch.
>
> Good, I've added them to my branch now.
This entire patch set should go in during a single merge window. I
will not send any pull request until I'm sure all patches will be
merged.
So far (if I'm not mistaken), only the patches I've already added to
next have appeared next. I can take the rest of the patches, too, but
I need OK for the following:
Jarkko, you seem happy with the following patches
- KEYS: trusted: Migrate to use tee specific driver registration function
- KEYS: trusted: Make use of tee bus methods
- tpm/tpm_ftpm_tee: Make use of tee specific driver registration
- tpm/tpm_ftpm_tee: Make use of tee bus methods
OK if I take them via my tree, or would you rather take them yourself?
Herbert, you seem happy with the following patches
- hwrng: optee - Make use of module_tee_client_driver()
- hwrng: optee - Make use of tee bus methods
OK if I take them via my tree, or would you rather take them yourself?
Sudeep, you seem happy with the following patches
- firmware: arm_scmi: optee: Make use of module_tee_client_driver()
- firmware: arm_scmi: Make use of tee bus methods
OK if I take them via my tree, or would you rather take them yourself?
Michael, Pavan, are you OK with the following patches
- firmware: tee_bnxt: Make use of module_tee_client_driver()
- firmware: tee_bnxt: Make use of tee bus methods
OK if I take them via my tree, or would you rather take them yourself?
Thanks,
Jens
^ permalink raw reply
* Re: [RFC PATCH 0/1] lsm: Add hook unix_path_connect
From: Kuniyuki Iwashima @ 2026-01-05 7:46 UTC (permalink / raw)
To: Justin Suess
Cc: Paul Moore, James Morris, Serge E . Hallyn, Simon Horman,
Mickaël Salaün, Günther Noack,
linux-security-module, Tingmao Wang, netdev
In-Reply-To: <20251231213314.2979118-1-utilityemal77@gmail.com>
On Wed, Dec 31, 2025 at 1:33 PM Justin Suess <utilityemal77@gmail.com> wrote:
>
> Hi,
>
> This patch introduces a new LSM hook unix_path_connect.
>
> The idea for this patch and the hook came from Günther Noack, who
> is cc'd. Much credit to him for the idea and discussion.
>
> This patch is based on the lsm next branch.
>
> Motivation
> ---
>
> For AF_UNIX sockets bound to a filesystem path (aka named sockets), one
> identifying object from a policy perspective is the path passed to
> connect(2). However, this operation currently restricts LSMs that rely
> on VFS-based mediation, because the pathname resolved during connect()
> is not preserved in a form visible to existing hooks before connection
> establishment.
Why can't LSM use unix_sk(other)->path in security_unix_stream_connect()
and security_unix_may_send() ?
> As a result, LSMs such as Landlock cannot currently
> restrict connections to named UNIX domain sockets by their VFS path.
>
> This gap has been discussed previously (e.g. in the context of Landlock's
> path-based access controls). [1] [2]
>
> I've cc'd the netdev folks as well on this, as the placement of this hook is
> important and in a core unix socket function.
>
> Design Choices
> ---
>
> The hook is called in net/unix/af_unix.c in the function unix_find_bsd().
>
> The hook takes a single parameter, a const struct path* to the named unix
> socket to which the connection is being established.
>
> The hook takes place after normal permissions checks, and after the
> inode is determined to be a socket. It however, takes place before
> the socket is actually connected to.
>
> If the hook returns non-zero it will do a put on the path, and return.
>
> References
> ---
>
> [1]: https://github.com/landlock-lsm/linux/issues/36#issue-2354007438
> [2]: https://lore.kernel.org/linux-security-module/cover.1767115163.git.m@maowtm.org/
>
> Kind Regards,
> Justin Suess
>
> Justin Suess (1):
> lsm: Add hook unix_path_connect
>
> include/linux/lsm_hook_defs.h | 1 +
> include/linux/security.h | 6 ++++++
> net/unix/af_unix.c | 8 ++++++++
> security/security.c | 16 ++++++++++++++++
> 4 files changed, 31 insertions(+)
>
>
> base-commit: 1c0860d4415d52f3ad1c8e0a15c1272869278a06
> --
> 2.51.0
>
^ permalink raw reply
* [PATCH v2 3/3] landlock: Document audit blocker field format
From: Samasth Norway Ananda @ 2026-01-03 0:27 UTC (permalink / raw)
To: mic, gnoack; +Cc: linux-security-module, linux-kernel
In-Reply-To: <20260103002722.1465371-1-samasth.norway.ananda@oracle.com>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 3176 bytes --]
Add comprehensive documentation for the ``blockers`` field format
in AUDIT_LANDLOCK_ACCESS records, including all possible prefixes
(fs., net., scope.) and their meanings.
Also fix a typo and update the documentation date to reflect these
changes.
Signed-off-by: Samasth Norway Ananda <samasth.norway.ananda@oracle.com>
---
Documentation/admin-guide/LSM/landlock.rst | 35 ++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/Documentation/admin-guide/LSM/landlock.rst b/Documentation/admin-guide/LSM/landlock.rst
index 9e61607def08..9923874e2156 100644
--- a/Documentation/admin-guide/LSM/landlock.rst
+++ b/Documentation/admin-guide/LSM/landlock.rst
@@ -6,7 +6,7 @@ Landlock: system-wide management
================================
:Author: Mickaël Salaün
-:Date: March 2025
+:Date: January 2026
Landlock can leverage the audit framework to log events.
@@ -38,6 +38,37 @@ AUDIT_LANDLOCK_ACCESS
domain=195ba459b blockers=fs.refer path="/usr/bin" dev="vda2" ino=351
domain=195ba459b blockers=fs.make_reg,fs.refer path="/usr/local" dev="vda2" ino=365
+
+ The ``blockers`` field uses dot-separated prefixes to indicate the type of
+ restriction that caused the denial:
+
+ **fs.*** - Filesystem access rights (ABI 1+):
+ - fs.execute, fs.write_file, fs.read_file, fs.read_dir
+ - fs.remove_dir, fs.remove_file
+ - fs.make_char, fs.make_dir, fs.make_reg, fs.make_sock
+ - fs.make_fifo, fs.make_block, fs.make_sym
+ - fs.refer (ABI 2+)
+ - fs.truncate (ABI 3+)
+ - fs.ioctl_dev (ABI 5+)
+
+ **net.*** - Network access rights (ABI 4+):
+ - net.bind_tcp - TCP port binding was denied
+ - net.connect_tcp - TCP connection was denied
+
+ **scope.*** - IPC scoping restrictions (ABI 6+):
+ - scope.abstract_unix_socket - Abstract UNIX socket connection denied
+ - scope.signal - Signal sending denied
+
+ Multiple blockers can appear in a single event (comma-separated) when
+ multiple access rights are missing. For example, creating a regular file
+ in a directory that lacks both ``make_reg`` and ``refer`` rights would show
+ ``blockers=fs.make_reg,fs.refer``.
+
+ The object identification fields (path, dev, ino for filesystem; opid,
+ ocomm for signals) depend on the type of access being blocked and provide
+ context about what resource was involved in the denial.
+
+
AUDIT_LANDLOCK_DOMAIN
This record type describes the status of a Landlock domain. The ``status``
field can be either ``allocated`` or ``deallocated``.
@@ -86,7 +117,7 @@ This command generates two events, each identified with a unique serial
number following a timestamp (``msg=audit(1729738800.268:30)``). The first
event (serial ``30``) contains 4 records. The first record
(``type=LANDLOCK_ACCESS``) shows an access denied by the domain `1a6fdc66f`.
-The cause of this denial is signal scopping restriction
+The cause of this denial is signal scoping restriction
(``blockers=scope.signal``). The process that would have receive this signal
is the init process (``opid=1 ocomm="systemd"``).
--
2.50.1
^ permalink raw reply related
* [PATCH v2 0/3] landlock: Documentation improvements
From: Samasth Norway Ananda @ 2026-01-03 0:27 UTC (permalink / raw)
To: mic, gnoack; +Cc: linux-security-module, linux-kernel
This series improves Landlock documentation to address gaps in ABI
compatibility handling, errata documentation, and audit field formats.
Changes since v1:
Patch 1: Add backwards compatibility section for restrict flags, fix
/usr rule description.
Patch 2: Enhance existing DOC sections with Impact descriptions, add
errata usage documentation.
Patch 3: Document audit blocker field format.
Samasth Norway Ananda (3):
landlock: Add missing ABI 7 case in documentation example
landlock: Add comprehensive errata documentation
landlock: Document audit blocker field format
Documentation/admin-guide/LSM/landlock.rst | 35 +++++++-
Documentation/userspace-api/landlock.rst | 95 ++++++++++++++++++++--
security/landlock/errata/abi-1.h | 8 ++
security/landlock/errata/abi-4.h | 7 ++
security/landlock/errata/abi-6.h | 10 +++
security/landlock/syscalls.c | 4 +-
6 files changed, 151 insertions(+), 8 deletions(-)
--
2.50.1
^ permalink raw reply
* [PATCH v2 1/3] landlock: Add missing ABI 7 case in documentation example
From: Samasth Norway Ananda @ 2026-01-03 0:27 UTC (permalink / raw)
To: mic, gnoack; +Cc: linux-security-module, linux-kernel
In-Reply-To: <20260103002722.1465371-1-samasth.norway.ananda@oracle.com>
Add the missing case 6 and case 7 handling in the ABI version
compatibility example to properly handle ABI < 7 kernels.
Add an optional backwards compatibility section for restrict flags
between the case analysis and landlock_restrict_self() call. The main
tutorial example remains unchanged with
landlock_restrict_self(ruleset_fd, 0) to keep it simple for users who
don't need logging flags.
Also fix misleading description of the /usr rule which incorrectly
stated it "only allow[s] reading" when the code actually allows both
reading and executing (LANDLOCK_ACCESS_FS_EXECUTE is included in
allowed_access).
Signed-off-by: Samasth Norway Ananda <samasth.norway.ananda@oracle.com>
---
Documentation/userspace-api/landlock.rst | 35 +++++++++++++++++++++---
1 file changed, 31 insertions(+), 4 deletions(-)
diff --git a/Documentation/userspace-api/landlock.rst b/Documentation/userspace-api/landlock.rst
index 1d0c2c15c22e..650c7b368561 100644
--- a/Documentation/userspace-api/landlock.rst
+++ b/Documentation/userspace-api/landlock.rst
@@ -127,6 +127,12 @@ version, and only use the available subset of access rights:
/* Removes LANDLOCK_SCOPE_* for ABI < 6 */
ruleset_attr.scoped &= ~(LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
LANDLOCK_SCOPE_SIGNAL);
+ __attribute__((fallthrough));
+ case 6:
+ /* Removes logging flags for ABI < 7 */
+ __attribute__((fallthrough));
+ case 7:
+ break;
}
This enables the creation of an inclusive ruleset that will contain our rules.
@@ -142,8 +148,9 @@ This enables the creation of an inclusive ruleset that will contain our rules.
}
We can now add a new rule to this ruleset thanks to the returned file
-descriptor referring to this ruleset. The rule will only allow reading the
-file hierarchy ``/usr``. Without another rule, write actions would then be
+descriptor referring to this ruleset. The rule will allow reading and
+executing files in the ``/usr`` hierarchy. Without another rule, write actions
+and other operations (make_dir, remove_file, etc.) would then be
denied by the ruleset. To add ``/usr`` to the ruleset, we open it with the
``O_PATH`` flag and fill the &struct landlock_path_beneath_attr with this file
descriptor.
@@ -191,10 +198,30 @@ number for a specific action: HTTPS connections.
err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
&net_port, 0);
+Backwards compatibility for restrict flags
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When passing a non-zero ``flags`` argument to ``landlock_restrict_self()``, the
+following backwards compatibility check needs to be taken into account:
+
+.. code-block:: c
+
+ /*
+ * Desired restriction flags, see ABI version section above.
+ * This value is only an example and differs by use case.
+ */
+ int restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON;
+ if (abi < 7) {
+ /* Clear logging flags unsupported in ABI < 7 */
+ restrict_flags &= ~(LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF |
+ LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON |
+ LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF);
+ }
+
The next step is to restrict the current thread from gaining more privileges
(e.g. through a SUID binary). We now have a ruleset with the first rule
-allowing read access to ``/usr`` while denying all other handled accesses for
-the filesystem, and a second rule allowing HTTPS connections.
+allowing read and execute access to ``/usr`` while denying all other handled
+accesses for the filesystem, and a second rule allowing HTTPS connections.
.. code-block:: c
--
2.50.1
^ permalink raw reply related
* [PATCH v2 2/3] landlock: Add comprehensive errata documentation
From: Samasth Norway Ananda @ 2026-01-03 0:27 UTC (permalink / raw)
To: mic, gnoack; +Cc: linux-security-module, linux-kernel
In-Reply-To: <20260103002722.1465371-1-samasth.norway.ananda@oracle.com>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 7554 bytes --]
Add comprehensive documentation for the Landlock errata mechanism,
including how to query errata using LANDLOCK_CREATE_RULESET_ERRATA
and links to enhanced detailed descriptions in the kernel source.
Also enhance existing DOC sections in security/landlock/errata/abi-*.h
files with Impact sections, and update the code comment in syscalls.c
to remind developers to update errata documentation when applicable.
This addresses the gap where the kernel implements errata tracking
but provides no user-facing documentation on how to use it, while
improving the existing technical documentation in-place rather than
duplicating it.
Signed-off-by: Samasth Norway Ananda <samasth.norway.ananda@oracle.com>
---
Documentation/userspace-api/landlock.rst | 60 +++++++++++++++++++++++-
security/landlock/errata/abi-1.h | 8 ++++
security/landlock/errata/abi-4.h | 7 +++
security/landlock/errata/abi-6.h | 10 ++++
security/landlock/syscalls.c | 4 +-
5 files changed, 87 insertions(+), 2 deletions(-)
diff --git a/Documentation/userspace-api/landlock.rst b/Documentation/userspace-api/landlock.rst
index 650c7b368561..930723fd7c1a 100644
--- a/Documentation/userspace-api/landlock.rst
+++ b/Documentation/userspace-api/landlock.rst
@@ -8,7 +8,7 @@ Landlock: unprivileged access control
=====================================
:Author: Mickaël Salaün
-:Date: March 2025
+:Date: January 2026
The goal of Landlock is to enable restriction of ambient rights (e.g. global
filesystem or network access) for a set of processes. Because Landlock
@@ -458,6 +458,64 @@ system call:
printf("Landlock supports LANDLOCK_ACCESS_FS_REFER.\n");
}
+Landlock Errata
+---------------
+
+In addition to ABI versions, Landlock provides an errata mechanism to track
+fixes for issues that may affect backwards compatibility or require userspace
+awareness. The errata bitmask can be queried using:
+
+.. code-block:: c
+
+ int errata;
+
+ errata = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_ERRATA);
+ if (errata < 0) {
+ /* Landlock not available or disabled */
+ return 0;
+ }
+
+The returned value is a bitmask where each bit represents a specific erratum.
+If bit N is set (``errata & (1 << (N - 1))``), then erratum N has been fixed
+in the running kernel.
+
+.. warning::
+
+ **Most applications should NOT check errata.** In 99.9% of cases, checking
+ errata is unnecessary, increases code complexity, and can potentially
+ decrease protection if misused. For example, disabling the sandbox when an
+ erratum is not fixed could leave the system less secure than using
+ Landlock's best-effort protection. When in doubt, ignore errata.
+
+For detailed technical descriptions of each erratum, including their impact
+and when they affect applications, see the DOC sections in the kernel source:
+
+- **Erratum 1: TCP socket identification (ABI 4)** - See ``erratum_1`` in ``security/landlock/errata/abi-4.h``
+- **Erratum 2: Scoped signal handling (ABI 6)** - See ``erratum_2`` in ``security/landlock/errata/abi-6.h``
+- **Erratum 3: Disconnected directory handling (ABI 1)** - See ``erratum_3`` in ``security/landlock/errata/abi-1.h``
+
+How to Check for Errata
+~~~~~~~~~~~~~~~~~~~~~~~
+
+If you determine that your application needs to check for specific errata,
+use this pattern:
+
+.. code-block:: c
+
+ int errata = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_ERRATA);
+ if (errata >= 0) {
+ /* Check for specific erratum (1-indexed) */
+ if (errata & (1 << (erratum_number - 1))) {
+ /* Erratum N is fixed in this kernel */
+ } else {
+ /* Erratum N is NOT fixed - consider implications for your use case */
+ }
+ }
+
+**Important:** Only check errata if your application specifically relies on
+behavior that changed due to the fix. The fixes generally make Landlock less
+restrictive or more correct, not more restrictive.
+
The following kernel interfaces are implicitly supported by the first ABI
version. Features only supported from a specific version are explicitly marked
as such.
diff --git a/security/landlock/errata/abi-1.h b/security/landlock/errata/abi-1.h
index e8a2bff2e5b6..ba9895bf8ce1 100644
--- a/security/landlock/errata/abi-1.h
+++ b/security/landlock/errata/abi-1.h
@@ -12,5 +12,13 @@
* hierarchy down to its filesystem root and those from the related mount point
* hierarchy. This prevents access right widening through rename or link
* actions.
+ *
+ * Impact:
+ *
+ * Without this fix, it was possible to widen access rights through rename or
+ * link actions involving disconnected directories, potentially bypassing
+ * ``LANDLOCK_ACCESS_FS_REFER`` restrictions. This could allow privilege
+ * escalation in complex mount scenarios where directories become disconnected
+ * from their original mount points.
*/
LANDLOCK_ERRATUM(3)
diff --git a/security/landlock/errata/abi-4.h b/security/landlock/errata/abi-4.h
index c052ee54f89f..59574759dc1e 100644
--- a/security/landlock/errata/abi-4.h
+++ b/security/landlock/errata/abi-4.h
@@ -11,5 +11,12 @@
* :manpage:`bind(2)` and :manpage:`connect(2)` operations. This change ensures
* that only TCP sockets are subject to TCP access rights, allowing other
* protocols to operate without unnecessary restrictions.
+ *
+ * Impact:
+ *
+ * In kernels without this fix, using ``LANDLOCK_ACCESS_NET_BIND_TCP`` or
+ * ``LANDLOCK_ACCESS_NET_CONNECT_TCP`` would incorrectly restrict non-TCP
+ * stream protocols (SMC, MPTCP, SCTP), potentially breaking applications
+ * that rely on these protocols while using Landlock network restrictions.
*/
LANDLOCK_ERRATUM(1)
diff --git a/security/landlock/errata/abi-6.h b/security/landlock/errata/abi-6.h
index df7bc0e1fdf4..a3a48b2bf2db 100644
--- a/security/landlock/errata/abi-6.h
+++ b/security/landlock/errata/abi-6.h
@@ -15,5 +15,15 @@
* interaction between threads of the same process should always be allowed.
* This change ensures that any thread is allowed to send signals to any other
* thread within the same process, regardless of their domain.
+ *
+ * Impact:
+ *
+ * This problem only manifests when the userspace process is itself using
+ * :manpage:`libpsx(3)` or an equivalent mechanism to enforce a Landlock policy
+ * on multiple already-running threads at once. Programs which enforce a
+ * Landlock policy at startup time and only then become multithreaded are not
+ * affected. Without this fix, signal scoping could break multi-threaded
+ * applications that expect threads within the same process to freely signal
+ * each other.
*/
LANDLOCK_ERRATUM(2)
diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c
index 0116e9f93ffe..cf5ba7715916 100644
--- a/security/landlock/syscalls.c
+++ b/security/landlock/syscalls.c
@@ -157,9 +157,11 @@ static const struct file_operations ruleset_fops = {
/*
* The Landlock ABI version should be incremented for each new Landlock-related
* user space visible change (e.g. Landlock syscalls). This version should
- * only be incremented once per Linux release, and the date in
+ * only be incremented once per Linux release. When incrementing, the date in
* Documentation/userspace-api/landlock.rst should be updated to reflect the
* UAPI change.
+ * If the change involves a fix that requires userspace awareness, also update
+ * the errata documentation in Documentation/userspace-api/landlock.rst.
*/
const int landlock_abi_version = 7;
--
2.50.1
^ permalink raw reply related
* Re: [RFC PATCH 0/5] landlock: Pathname-based UNIX connect() control
From: Demi Marie Obenour @ 2026-01-02 18:37 UTC (permalink / raw)
To: Günther Noack
Cc: Tingmao Wang, Mickaël Salaün, Paul Moore,
linux-security-module, Justin Suess, Samasth Norway Ananda,
Matthieu Buffet, Mikhail Ivanov, konstantin.meskhidze,
Alyssa Ross, Jann Horn, Tahera Fahimi
In-Reply-To: <20260102.17e1c2b9faa4@gnoack.org>
[-- Attachment #1.1.1: Type: text/plain, Size: 2393 bytes --]
On 1/2/26 05:50, Günther Noack wrote:
> On Fri, Jan 02, 2026 at 05:27:40AM -0500, Demi Marie Obenour wrote:
>> On 1/2/26 05:16, Günther Noack wrote:
>>> On Thu, Jan 01, 2026 at 05:44:51PM -0500, Demi Marie Obenour wrote:
>>>> On 1/1/26 17:34, Tingmao Wang wrote:
>>>>> On 1/1/26 22:14, Demi Marie Obenour wrote:
>>>>>> [...]
>>>>>> Does this leave directory traversal as the only missing Landlock
>>>>>> filesystem access control? Ideally Landlock could provide the same
>>>>>> isolation from the filesystem that mount namespaces do.
>>>>>
>>>>> I think that level of isolation would require path walk control - see:
>>>>> https://github.com/landlock-lsm/linux/issues/9
>>>>>
>>>>> (Landlock also doesn't currently control some metadata operations - see
>>>>> the warning at the end of the "Filesystem flags" section in [1])
>>>>>
>>>>> [1]: https://docs.kernel.org/6.18/userspace-api/landlock.html#filesystem-flags
>>>>
>>>> Could this replace all of the existing hooks?
>>>
>>> If you do not need to distinguish between the different operations
>>> which Landlock offers access rights for, but you only want to limit
>>> the visibility of directory hierarchies in the file system, then yes,
>>> the path walk control described in issue 9 would be sufficient and a
>>> more complete control.
>>>
>>> The path walk control is probably among the more difficult Landlock
>>> feature requests. A simple implementation would be easy to implement
>>> technically, but it also requires a new LSM hook which will have to
>>> get called *during* path lookup, and we'd have to make sure that the
>>> performance impact stays in check. Path lookup is after all a very
>>> central facility in a OS kernel.
>>
>> What about instead using the inode-based hooks for directory searching?
>> SELinux can already restrict that.
>
> Oh, thanks, good pointer! I was under the impression that this didn't
> exist yet -- I assume you are referring to the
> security_inode_follow_link() hook, which is already happening during
> path resolution?
I'm not familiar with existing LSM hooks, but I do know that SELinux
enforces checks on searching and reading directories and symlinks.
> I take it back then. :) If there is prior art, implementing this might
> be more feasible than I thought.
I think so too!
--
Sincerely,
Demi Marie Obenour (she/her/hers)
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 7253 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH v2 6/6] docs: trusted-encryped: add PKWM as a new trust source
From: Mimi Zohar @ 2026-01-02 17:48 UTC (permalink / raw)
To: Srish Srinivasan, linux-integrity, keyrings, linuxppc-dev
Cc: maddy, mpe, npiggin, christophe.leroy, James.Bottomley, jarkko,
nayna, rnsastry, linux-kernel, linux-security-module
In-Reply-To: <20251217172505.112398-7-ssrish@linux.ibm.com>
On Wed, 2025-12-17 at 22:55 +0530, Srish Srinivasan wrote:
> From: Nayna Jain <nayna@linux.ibm.com>
>
> Update Documentation/security/keys/trusted-encrypted.rst and Documentation/
> admin-guide/kernel-parameters.txt with PowerVM Key Wrapping Module (PKWM)
> as a new trust source
>
> Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
> Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
Thanks, Nayna, Srish.
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
^ permalink raw reply
* Re: [PATCH v2 5/6] keys/trusted_keys: establish PKWM as a trusted source
From: Mimi Zohar @ 2026-01-02 17:44 UTC (permalink / raw)
To: Srish Srinivasan, linux-integrity, keyrings, linuxppc-dev
Cc: maddy, mpe, npiggin, christophe.leroy, James.Bottomley, jarkko,
nayna, rnsastry, linux-kernel, linux-security-module
In-Reply-To: <20251217172505.112398-6-ssrish@linux.ibm.com>
On Wed, 2025-12-17 at 22:55 +0530, Srish Srinivasan wrote:
> The wrapping key does not exist by default and is generated by the
> hypervisor as a part of PKWM initialization. This key is then persisted by
> the hypervisor and is used to wrap trusted keys. These are variable length
> symmetric keys, which in the case of PowerVM Key Wrapping Module (PKWM) are
> generated using the kernel RNG. PKWM can be used as a trust source through
> the following example keyctl command
-> commands:
>
> keyctl add trusted my_trusted_key "new 32" @u
>
> Use the wrap_flags command option to set the secure boot requirement for
> the wrapping request through the following keyctl commands
>
> case1: no secure boot requirement. (default)
> keyctl usage: keyctl add trusted my_trusted_key "new 32" @u
> OR
> keyctl add trusted my_trusted_key "new 32 wrap_flags=0x00" @u
>
> case2: secure boot required to in either audit or enforce mode. set bit 0
> keyctl usage: keyctl add trusted my_trusted_key "new 32 wrap_flags=0x01" @u
>
> case3: secure boot required to be in enforce mode. set bit 1
> keyctl usage: keyctl add trusted my_trusted_key "new 32 wrap_flags=0x02" @u
>
> NOTE:
> -> Setting the secure boot requirement is NOT a must.
> -> Only either of the secure boot requirement options should be set. Not
> both.
> -> All the other bits are requied to be not set.
-> required
> -> Set the kernel parameter trusted.source=pkwm to choose PKWM as the
> backend for trusted keys implementation.
> -> CONFIG_PSERIES_PLPKS must be enabled to build PKWM.
>
> Add PKWM, which is a combination of IBM PowerVM and Power LPAR Platform
> KeyStore, as a new trust source for trusted keys.
>
> Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
Thanks, Srish. Other than fixing the typo and other suggestion above,
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
^ permalink raw reply
* Re: [PATCH v2 2/6] powerpc/pseries: move the PLPKS config inside its own sysfs directory
From: Mimi Zohar @ 2026-01-02 17:28 UTC (permalink / raw)
To: Srish Srinivasan, linux-integrity, keyrings, linuxppc-dev
Cc: maddy, mpe, npiggin, christophe.leroy, James.Bottomley, jarkko,
nayna, rnsastry, linux-kernel, linux-security-module
In-Reply-To: <20251217172505.112398-3-ssrish@linux.ibm.com>
On Wed, 2025-12-17 at 22:55 +0530, Srish Srinivasan wrote:
> The /sys/firmware/secvar/config directory represents Power LPAR Platform
> KeyStore (PLPKS) configuration properties such as max_object_size, signed_
> update_algorithms, supported_policies, total_size, used_space, and version.
> These attributes describe the PLPKS, and not the secure boot variables
> (secvars).
>
> Create /sys/firmware/plpks directory and move the PLPKS config inside this
> directory. For backwards compatibility, create a soft link from the secvar
> sysfs directory to this config and emit a warning stating that the older
> sysfs path has been deprecated. Separate out the plpks specific
> documentation from secvar.
>
> Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
LGTM.
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
^ permalink raw reply
* Re: [PATCH v2 4/6] pseries/plpks: add HCALLs for PowerVM Key Wrapping Module
From: Mimi Zohar @ 2026-01-02 17:25 UTC (permalink / raw)
To: Srish Srinivasan, linux-integrity, keyrings, linuxppc-dev
Cc: maddy, mpe, npiggin, christophe.leroy, James.Bottomley, jarkko,
nayna, rnsastry, linux-kernel, linux-security-module
In-Reply-To: <20251217172505.112398-5-ssrish@linux.ibm.com>
Hi Srish,
On Wed, 2025-12-17 at 22:55 +0530, Srish Srinivasan wrote:
> The hypervisor generated wrapping key is an AES-GCM-256 symmetric key which
> is stored in a non-volatile, secure, and encrypted storage called the Power
> LPAR Platform KeyStore. It has policy based protections that prevent it
> from being read out or exposed to the user.
>
> Implement H_PKS_GEN_KEY, H_PKS_WRAP_OBJECT, and H_PKS_UNWRAP_OBJECT HCALLs
> to enable using the PowerVM Key Wrapping Module (PKWM) as a new trust
> source for trusted keys. Disallow H_PKS_READ_OBJECT, H_PKS_SIGNED_UPDATE,
> and H_PKS_WRITE_OBJECT for objects with the 'wrapping key' policy set.
> Capture the availability status for the H_PKS_WRAP_OBJECT interface.
>
> Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
scripts/checkpatch.pl --codespell caught a couple of typos. Please fix the
typos here in in this patch and the one in v2 5/6.
> ---
> Documentation/arch/powerpc/papr_hcalls.rst | 43 +++
> arch/powerpc/include/asm/plpks.h | 10 +
> arch/powerpc/platforms/pseries/plpks.c | 345 ++++++++++++++++++++-
> 3 files changed, 396 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/arch/powerpc/papr_hcalls.rst b/Documentation/arch/powerpc/papr_hcalls.rst
> index 805e1cb9bab9..14e39f095a1c 100644
> --- a/Documentation/arch/powerpc/papr_hcalls.rst
> +++ b/Documentation/arch/powerpc/papr_hcalls.rst
> @@ -300,6 +300,49 @@ H_HTM supports setup, configuration, control and dumping of Hardware Trace
> Macro (HTM) function and its data. HTM buffer stores tracing data for functions
> like core instruction, core LLAT and nest.
>
> +**H_PKS_GEN_KEY**
> +
> +| Input: authorization, objectlabel, objectlabellen, policy, out, outlen
> +| Out: *Hypervisor Generated Key, or None when the wrapping key policy is set*
> +| Return Value: *H_SUCCESS, H_Function, H_State, H_R_State, H_Parameter, H_P2,
> + H_P3, H_P4, H_P5, H_P6, H_Authority, H_Nomem, H_Busy, H_Resource,
> + H_Aborted*
> +
> +H_PKS_GEN_KEY is used to have the hypervisor generate a new random key.
> +This key is stored as an object in the Power LPAR Platform KeyStore with
> +the provided object label. With the wrapping key policy set the key is only
> +visible to the hypervisor, while the key's label would still be visible to
> +the user. Generation of wrapping keys is supported only for a key size of
> +32 bytes.
> +
> +**H_PKS_WRAP_OBJECT**
> +
> +| Input: authorization, wrapkeylabel, wrapkeylabellen, objectwrapflags, in,
> +| inlen, out, outlen, continue-token
> +| Out: *continue-token, byte size of wrapped object, wrapped object*
> +| Return Value: *H_SUCCESS, H_Function, H_State, H_R_State, H_Parameter, H_P2,
> + H_P3, H_P4, H_P5, H_P6, H_P7, H_P8, H_P9, H_Authority, H_Invalid_Key,
> + H_NOT_FOUND, H_Busy, H_LongBusy, H_Aborted*
> +
> +H_PKS_WRAP_OBJECT is used to wrap an object using a wrapping key stored in the
> +Power LPAR Platform KeyStore and return the wrapped object to the caller. The
> +caller provides a label to a wrapping key with the 'wrapping key' policy set,
> +which must have been previously created with H_PKS_GEN_KEY. The provided object
> +is then encrypted with the wrapping key and additional metadata and the result
> +is returned to the caller.
> +
> +
> +**H_PKS_UNWRAP_OBJECT**
> +
> +| Input: authorization, objectwrapflags, in, inlen, out, outlen, continue-token
> +| Out: *continue-token, byte size of unwrapped object, unwrapped object*
> +| Return Value: *H_SUCCESS, H_Function, H_State, H_R_State, H_Parameter, H_P2,
> + H_P3, H_P4, H_P5, H_P6, H_P7, H_Authority, H_Unsupported, H_Bad_Data,
> + H_NOT_FOUND, H_Invalid_Key, H_Busy, H_LongBusy, H_Aborted*
> +
> +H_PKS_UNWRAP_OBJECT is used to unwrap an object that was previously warapped with
> +H_PKS_WRAP_OBJECT.
> +
> References
> ==========
> .. [1] "Power Architecture Platform Reference"
> diff --git a/arch/powerpc/include/asm/plpks.h b/arch/powerpc/include/asm/plpks.h
> index 8f034588fdf7..e87f90e40d4e 100644
> --- a/arch/powerpc/include/asm/plpks.h
> +++ b/arch/powerpc/include/asm/plpks.h
> @@ -113,6 +113,16 @@ void plpks_early_init_devtree(void);
> int plpks_populate_fdt(void *fdt);
>
> int plpks_config_create_softlink(struct kobject *from);
> +
> +bool plpks_wrapping_is_supported(void);
> +
> +int plpks_gen_wrapping_key(void);
> +
> +int plpks_wrap_object(u8 **input_buf, u32 input_len, u16 wrap_flags,
> + u8 **output_buf, u32 *output_len);
> +
> +int plpks_unwrap_object(u8 **input_buf, u32 input_len,
> + u8 **output_buf, u32 *output_len);
> #else // CONFIG_PSERIES_PLPKS
> static inline bool plpks_is_available(void) { return false; }
> static inline u16 plpks_get_passwordlen(void) { BUILD_BUG(); }
> diff --git a/arch/powerpc/platforms/pseries/plpks.c b/arch/powerpc/platforms/pseries/plpks.c
> index 4a08f51537c8..2ec04908b057 100644
> --- a/arch/powerpc/platforms/pseries/plpks.c
> +++ b/arch/powerpc/platforms/pseries/plpks.c
> @@ -9,6 +9,32 @@
>
> #define pr_fmt(fmt) "plpks: " fmt
>
> +#define PLPKS_WRAPKEY_COMPONENT "PLPKSWR"
> +#define PLPKS_WRAPKEY_NAME "default-wrapping-key"
> +
> +/*
> + * To 4K align the {input, output} buffers to the {UN}WRAP H_CALLs
> + */
> +#define PLPKS_WRAPPING_BUF_ALIGN 4096
> +
> +/*
> + * To ensure the output buffer's length is at least 1024 bytes greater
> + * than the input buffer's length during the WRAP H_CALL
> + */
> +#define PLPKS_WRAPPING_BUF_DIFF 1024
> +
> +#define PLPKS_WRAP_INTERFACE_BIT 3
> +#define PLPKS_WRAPPING_KEY_LENGTH 32
> +
> +#define WRAPFLAG_BE_BIT_SET(be_bit) \
> + BIT_ULL(63 - (be_bit))
> +
> +#define WRAPFLAG_BE_GENMASK(be_bit_hi, be_bit_lo) \
> + GENMASK_ULL(63 - (be_bit_hi), 63 - (be_bit_lo))
> +
> +#define WRAPFLAG_BE_FIELD_PREP(be_bit_hi, be_bit_lo, val) \
> + FIELD_PREP(WRAPFLAG_BE_GENMASK(be_bit_hi, be_bit_lo), (val))
> +
> #include <linux/delay.h>
> #include <linux/errno.h>
> #include <linux/io.h>
> @@ -39,6 +65,7 @@ static u32 supportedpolicies;
> static u32 maxlargeobjectsize;
> static u64 signedupdatealgorithms;
> static u64 wrappingfeatures;
> +static bool wrapsupport;
>
> struct plpks_auth {
> u8 version;
> @@ -283,6 +310,7 @@ static int _plpks_get_config(void)
> maxlargeobjectsize = be32_to_cpu(config->maxlargeobjectsize);
> signedupdatealgorithms = be64_to_cpu(config->signedupdatealgorithms);
> wrappingfeatures = be64_to_cpu(config->wrappingfeatures);
> + wrapsupport = config->flags & PPC_BIT8(PLPKS_WRAP_INTERFACE_BIT);
>
> // Validate that the numbers we get back match the requirements of the spec
> if (maxpwsize < 32) {
> @@ -614,6 +642,9 @@ int plpks_signed_update_var(struct plpks_var *var, u64 flags)
> if (!(var->policy & PLPKS_SIGNEDUPDATE))
> return -EINVAL;
>
> + if (var->policy & PLPKS_WRAPPINGKEY)
> + return -EINVAL;
> +
> // Signed updates need the component to be NULL.
> if (var->component)
> return -EINVAL;
> @@ -696,6 +727,9 @@ int plpks_write_var(struct plpks_var var)
> if (var.policy & PLPKS_SIGNEDUPDATE)
> return -EINVAL;
>
> + if (var.policy & PLPKS_WRAPPINGKEY)
> + return -EINVAL;
> +
> auth = construct_auth(PLPKS_OS_OWNER);
> if (IS_ERR(auth))
> return PTR_ERR(auth);
> @@ -790,6 +824,9 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var)
> if (var->namelen > PLPKS_MAX_NAME_SIZE)
> return -EINVAL;
>
> + if (var->policy & PLPKS_WRAPPINGKEY)
> + return -EINVAL;
> +
> auth = construct_auth(consumer);
> if (IS_ERR(auth))
> return PTR_ERR(auth);
> @@ -845,8 +882,312 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var)
> }
>
> /**
> - * plpks_read_os_var() - Fetch the data for the specified variable that is
> - * owned by the OS consumer.
> + * plpks_wrapping_is_supported() - Get the H_PKS_WRAP_OBJECT interface
> + * availability status for the LPAR.
> + *
> + * Successful execution of the H_PKS_GET_CONFIG HCALL during initialization
> + * sets bit 3 of the flags variable in the PLPKS config structure if the
> + * H_PKS_WRAP_OBJECT interface is supported.
> + *
> + * Returns: true if the H_PKS_WRAP_OBJECT interface is supported, false if not.
> + */
> +bool plpks_wrapping_is_supported(void)
> +{
> + return wrapsupport;
> +}
> +
> +/**
> + * plpks_gen_wrapping_key() - Generate a new random key with the 'wrapping key'
> + * policy set.
> + *
> + * The H_PKS_GEN_KEY HCALL makes the hypervisor generate a new random key and
> + * store the key in a PLPKS object with the provided object label. With the
> + * 'wrapping key' policy set, only the label to the newly generated random key
> + * would be visible to the user.
> + *
> + * Possible reasons for the returned errno values:
> + *
> + * -ENXIO if PLPKS is not supported
> + * -EIO if PLPKS access is blocked due to the LPAR's state
> + * if PLPKS modification is blocked due to the LPAR's state
> + * if an error occurred while processing the request
> + * -EINVAL if invalid authorization parameter
> + * if invalid object label parameter
> + * if invalid object label len parameter
> + * if invalid or unsupported policy declaration
> + * if invalid output buffer parameter
> + * if invalid output buffer length parameter
> + * -EPERM if access is denied
> + * -ENOMEM if there is inadequate memory to perform this operation
> + * -EBUSY if unable to handle the request
> + * -EEXIST if the object label already exists
> + *
> + * Returns: On success 0 is returned, a negative errno if not.
> + */
> +int plpks_gen_wrapping_key(void)
> +{
> + unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
> + struct plpks_auth *auth;
> + struct label *label;
> + int rc = 0, pseries_status = 0;
> + struct plpks_var var = {
> + .name = PLPKS_WRAPKEY_NAME,
> + .namelen = strlen(var.name),
> + .policy = PLPKS_WRAPPINGKEY,
> + .os = PLPKS_VAR_LINUX,
> + .component = PLPKS_WRAPKEY_COMPONENT
> + };
> +
> + auth = construct_auth(PLPKS_OS_OWNER);
> + if (IS_ERR(auth))
> + return PTR_ERR(auth);
> +
> + label = construct_label(var.component, var.os, var.name, var.namelen);
> + if (IS_ERR(label)) {
> + rc = PTR_ERR(label);
> + goto out;
> + }
> +
> + rc = plpar_hcall(H_PKS_GEN_KEY, retbuf,
> + virt_to_phys(auth), virt_to_phys(label),
> + label->size, var.policy,
> + NULL, PLPKS_WRAPPING_KEY_LENGTH);
> +
> + if (!rc)
> + rc = plpks_confirm_object_flushed(label, auth);
> +
> + pseries_status = rc;
> + rc = pseries_status_to_err(rc);
> +
> + if (rc && rc != -EEXIST) {
> + pr_err("H_PKS_GEN_KEY failed.");
> + pr_err("pseries_status = %d, error code = %d", pseries_status,
> + rc);
> + } else {
> + rc = 0;
> + }
> +
> + kfree(label);
> +out:
> + kfree(auth);
> + return rc;
> +}
> +EXPORT_SYMBOL_GPL(plpks_gen_wrapping_key);
> +
> +/**
> + * plpks_wrap_object() - Wrap an object using the default wrapping key stored in
> + * the PLPKS.
> + * @input_buf: buffer containing the data to be wrapped
> + * @input_len: length of the input buffer
> + * @wrap_flags: object wrapping flags
> + * @output_buf: buffer to store the wrapped data
> + * @output_len: length of the output buffer
> + *
> + * The H_PKS_WRAP_OBJECT HCALL wraps an object using a wrapping key stored in
> + * the PLPKS and returns the wrapped object to the caller. The caller provides a
> + * label to the wrapping key with the 'wrapping key' policy set that must have
> + * been previously created with the H_PKS_GEN_KEY HCALL. The provided object is
> + * then encrypted with the wrapping key and additional metadata and the result
> + * is returned to the user. The metadata includes the wrapping algorithm and the
> + * wrapping key name so those parameters are not required during unwrap.
> + *
> + * Possible reasons for the returned errno values:
> + *
> + * -ENXIO if PLPKS is not supported
> + * -EIO if PLPKS access is blocked due to the LPAR's state
> + * if PLPKS modification is blocked due to the LPAR's state
> + * if an error occurred while processing the request
> + * -EINVAL if invalid authorization parameter
> + * if invalid wraping key label parameter
-> wrapping
> + * if invalid wrapping key label length parameter
> + * if invalid or unsupported object wrapping flags
> + * if invalid inut buffer parameter
-> input
> + * if invalid input buffer length parameter
> + * if invalid output buffer parameter
> + * if invalid output buffer length parameter
> + * if invalid continue token parameter
> + * if the wrapping key is not compatible with the wrapping
> + * algorithm
> + * -EPERM if access is denied
> + * -ENOENT if the requested wrapping key was not found
> + * -EBUSY if unable to handle the request or long running operation
> + * initiated, retry later.
> + *
> + * Returns: On success 0 is returned, a negative errno if not.
> + */
> +int plpks_wrap_object(u8 **input_buf, u32 input_len, u16 wrap_flags,
> + u8 **output_buf, u32 *output_len)
> +{
> + unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = { 0 };
> + struct plpks_auth *auth;
> + struct label *label;
> + u64 continuetoken = 0;
> + u64 objwrapflags = 0;
> + int rc = 0, pseries_status = 0;
> + bool sb_audit_or_enforce_bit = wrap_flags & BIT(0);
> + bool sb_enforce_bit = wrap_flags & BIT(1);
> + struct plpks_var var = {
> + .name = PLPKS_WRAPKEY_NAME,
> + .namelen = strlen(var.name),
> + .os = PLPKS_VAR_LINUX,
> + .component = PLPKS_WRAPKEY_COMPONENT
> + };
> +
> + auth = construct_auth(PLPKS_OS_OWNER);
> + if (IS_ERR(auth))
> + return PTR_ERR(auth);
> +
> + label = construct_label(var.component, var.os, var.name, var.namelen);
> + if (IS_ERR(label)) {
> + rc = PTR_ERR(label);
> + goto out;
> + }
> +
> + /* Set the consumer password requirement bit. A must have. */
> + objwrapflags |= WRAPFLAG_BE_BIT_SET(3);
> +
> + /* Set the wrapping algorithm bit. Just one algorithm option for now */
> + objwrapflags |= WRAPFLAG_BE_FIELD_PREP(60, 63, 0x1);
> +
> + if (sb_audit_or_enforce_bit & sb_enforce_bit) {
> + pr_err("Cannot set both audit/enforce and enforce bits.");
> + rc = -EINVAL;
> + goto out_free_label;
> + } else if (sb_audit_or_enforce_bit) {
> + objwrapflags |= WRAPFLAG_BE_BIT_SET(1);
> + } else if (sb_enforce_bit) {
> + objwrapflags |= WRAPFLAG_BE_BIT_SET(2);
> + }
> +
> + *output_len = input_len + PLPKS_WRAPPING_BUF_DIFF;
> +
> + *output_buf = kzalloc(ALIGN(*output_len, PLPKS_WRAPPING_BUF_ALIGN),
> + GFP_KERNEL);
> + if (!(*output_buf)) {
> + pr_err("Output buffer allocation failed. Returning -ENOMEM.");
> + rc = -ENOMEM;
> + goto out_free_label;
> + }
> +
> + do {
> + rc = plpar_hcall9(H_PKS_WRAP_OBJECT, retbuf,
> + virt_to_phys(auth), virt_to_phys(label),
> + label->size, objwrapflags,
> + virt_to_phys(*input_buf), input_len,
> + virt_to_phys(*output_buf), *output_len,
> + continuetoken);
> +
> + continuetoken = retbuf[0];
> + pseries_status = rc;
> + rc = pseries_status_to_err(rc);
> + } while (rc == -EBUSY);
> +
> + if (rc) {
> + pr_err("H_PKS_WRAP_OBJECT failed.");
> + pr_err("pseries_status = %d, return code = %d", pseries_status,
> + rc);
> + kfree(*output_buf);
> + *output_buf = NULL;
> + } else {
> + *output_len = retbuf[1];
> + }
> +
> +out_free_label:
> + kfree(label);
> +out:
> + kfree(auth);
> + return rc;
> +}
> +EXPORT_SYMBOL_GPL(plpks_wrap_object);
> +
> +/**
> + * plpks_unwrap_object() - Unwrap an object using the default wrapping key
> + * stored in the PLPKS.
> + * @input_buf: buffer containing the data to be unwrapped
> + * @input_len: length of the input buffer
> + * @output_buf: buffer to store the unwrapped data
> + * @output_len: length of the output buffer
> + *
> + * The H_PKS_UNWRAP_OBJECT HCALL unwraps an object that was previously wrapped
> + * using the H_PKS_WRAP_OBJECT HCALL.
> + *
> + * Possible reasons for the returned errno values:
> + *
> + * -ENXIO if PLPKS is not supported
> + * -EIO if PLPKS access is blocked due to the LPAR's state
> + * if PLPKS modification is blocked due to the LPAR's state
> + * if an error occurred while processing the request
> + * -EINVAL if invalid authorization parameter
> + * if invalid or unsupported object unwrapping flags
> + * if invalid inut buffer parameter
-> input
> + * if invalid input buffer length parameter
> + * if invalid output buffer parameter
> + * if invalid output buffer length parameter
> + * if invalid continue token parameter
> + * if the wrapping key is not compatible with the wrapping
> + * algorithm
> + * if the wrapped object's format is not supported
> + * if the wrapped object is invalid
> + * -EPERM if access is denied
> + * -ENOENT if the wrapping key for the provided object was not found
> + * -EBUSY if unable to handle the request or long running operation
> + * initiated, retry later.
> + *
> + * Returns: On success 0 is returned, a negative errno if not.
> + */
> +int plpks_unwrap_object(u8 **input_buf, u32 input_len, u8 **output_buf,
> + u32 *output_len)
> +{
> + unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = { 0 };
> + struct plpks_auth *auth;
> + u64 continuetoken = 0;
> + u64 objwrapflags = 0;
> + int rc = 0, pseries_status = 0;
> +
> + auth = construct_auth(PLPKS_OS_OWNER);
> + if (IS_ERR(auth))
> + return PTR_ERR(auth);
> +
> + *output_len = input_len - PLPKS_WRAPPING_BUF_DIFF;
> + *output_buf = kzalloc(ALIGN(*output_len, PLPKS_WRAPPING_BUF_ALIGN),
> + GFP_KERNEL);
> + if (!(*output_buf)) {
> + pr_err("Output buffer allocation failed. Returning -ENOMEM.");
> + rc = -ENOMEM;
> + goto out;
> + }
> +
> + do {
> + rc = plpar_hcall9(H_PKS_UNWRAP_OBJECT, retbuf,
> + virt_to_phys(auth), objwrapflags,
> + virt_to_phys(*input_buf), input_len,
> + virt_to_phys(*output_buf), *output_len,
> + continuetoken);
> +
> + continuetoken = retbuf[0];
> + pseries_status = rc;
> + rc = pseries_status_to_err(rc);
> + } while (rc == -EBUSY);
> +
> + if (rc) {
> + pr_err("H_PKS_UNWRAP_OBJECT failed.");
> + pr_err("pseries_status = %d, return code = %d", pseries_status,
> + rc);
> + kfree(*output_buf);
> + *output_buf = NULL;
> + } else {
> + *output_len = retbuf[1];
> + }
> +
> +out:
> + kfree(auth);
> + return rc;
> +}
> +EXPORT_SYMBOL_GPL(plpks_unwrap_object);
> +
> +/**
> + * plpks_read_os_var() - Fetch the data for the specified variable that is owned
> + * by the OS consumer.
> * @var: variable to be read from the PLPKS
> *
> * The consumer or the owner of the object is the os kernel. The
^ permalink raw reply
* Re: [PATCH v2 1/6] pseries/plpks: fix kernel-doc comment inconsistencies
From: Mimi Zohar @ 2026-01-02 17:23 UTC (permalink / raw)
To: Srish Srinivasan, linux-integrity, keyrings, linuxppc-dev
Cc: maddy, mpe, npiggin, christophe.leroy, James.Bottomley, jarkko,
nayna, rnsastry, linux-kernel, linux-security-module
In-Reply-To: <20251217172505.112398-2-ssrish@linux.ibm.com>
On Wed, 2025-12-17 at 22:55 +0530, Srish Srinivasan wrote:
> Fix issues with comments for all the applicable functions to be
> consistent with kernel-doc format. Move them before the function
> definition as opposed to the function prototype.
>
> Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
Thanks Srish for moving and fixing the kernel documentation.
--
Mimi
^ permalink raw reply
* Re: [PATCH v8 03/12] tpm: Orchestrate TPM commands in tpm_get_random()
From: Jarkko Sakkinen @ 2026-01-02 16:40 UTC (permalink / raw)
To: Jonathan McDowell
Cc: linux-integrity, Eric Biggers, Peter Huewe, Jason Gunthorpe,
David Howells, Paul Moore, James Morris, Serge E. Hallyn,
open list, open list:KEYS/KEYRINGS, open list:SECURITY SUBSYSTEM
In-Reply-To: <aUUeP5qhEISjythp@earth.li>
On Fri, Dec 19, 2025 at 09:43:27AM +0000, Jonathan McDowell wrote:
> On Tue, Dec 16, 2025 at 11:21:37AM +0200, Jarkko Sakkinen wrote:
> > tpm1_get_random() and tpm2_get_random() contain duplicate orchestration
> > code. Consolidate orchestration to tpm_get_random().
>
> Does keeping the respective tpm1/tpm2 bits in their -cmd.c files not make
> more sense, still allowing for the consolidation of orchestration in
> tpm_get_random?
Yeah, especially after not paying attention to this for couple of weeks
this really feels like unnecessary. It would also reduce the overall
delta caused by these patches. I will take here step back and retain
the helpers in tpm1/tpm2-cmd.c files.
BR, Jarkko
^ permalink raw reply
* Re: [PATCH v8 04/12] tpm: Change tpm_get_random() opportunistic
From: Jarkko Sakkinen @ 2026-01-02 16:37 UTC (permalink / raw)
To: Jonathan McDowell
Cc: linux-integrity, David S . Miller, Herbert Xu, Eric Biggers,
Peter Huewe, Jason Gunthorpe, David Howells, Paul Moore,
James Morris, Serge E. Hallyn, open list, open list:KEYS/KEYRINGS,
open list:SECURITY SUBSYSTEM
In-Reply-To: <aUUd760l89lrNOs-@earth.li>
On Fri, Dec 19, 2025 at 09:42:07AM +0000, Jonathan McDowell wrote:
> On Tue, Dec 16, 2025 at 11:21:38AM +0200, Jarkko Sakkinen wrote:
> > hwrng framework does not have a requirement that the all bytes requested
> > need to be provided. By enforcing such a requirement internally, TPM driver
> > can cause unpredictability in latency, as a single tpm_get_random() call
> > can result multiple TPM commands.
> >
> > Especially, when TCG_TPM2_HMAC is enabled, extra roundtrips could have
> > significant effect to the system latency.
> >
> > Thus, send TPM command only once and return bytes received instead of
> > committing to the number of requested bytes.
>
> Function comment for tpm_get_random needs updated as well, as it currently
> says "until all of the @max bytes have been received", which is no longer
> true with this patch. With that:
>
> Reviewed-by: Jonathan McDowell <noodles@meta.com>
Thank you and definitely can refine that comment. After holidays it is
probably to go through this patch set with time and send +1 iteration
:-)
BR, Jarkko
^ permalink raw reply
* Re: [PATCH v8 05/12] tpm2-sessions: Define TPM2_NAME_MAX_SIZE
From: Jarkko Sakkinen @ 2026-01-02 16:35 UTC (permalink / raw)
To: Jonathan McDowell
Cc: linux-integrity, Peter Huewe, Jason Gunthorpe, David Howells,
Paul Moore, James Morris, Serge E. Hallyn, open list,
open list:KEYS/KEYRINGS, open list:SECURITY SUBSYSTEM
In-Reply-To: <aUUbkosWlOjZ48YP@earth.li>
On Fri, Dec 19, 2025 at 09:32:02AM +0000, Jonathan McDowell wrote:
> On Tue, Dec 16, 2025 at 11:21:39AM +0200, Jarkko Sakkinen wrote:
> > Define TPM2_NAME_MAX_SIZE, which describes the maximum size for hashes
> > encoded as TPMT_HA, which the prime identifier used for persistent and
> > transient keys in TPM2 protocol.
> >
> > Set its value to 'SHA512_DIGEST_SIZE + 2', as SHA512 has the largest
> > digest size of the algorithms in TCG algorithm repository.
> >
> > In additionl, rename TPM2_NAME_SIZE as TPM2_NULL_NAME_SIZE in order to
> > avoid any possible confusion.
>
> One minor capitalisation nit, otherwise:
>
> Reviewed-by: Jonathan McDowell <noodles@meta.com>
>
> > Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
> > ---
> > v6:
> > - Rewrote the commit message.
> > v2:
> > - Rename TPM2_NAME_SIZE as TPM2_NULL_NAME_SIZE.
> > ---
> > drivers/char/tpm/tpm-sysfs.c | 2 +-
> > drivers/char/tpm/tpm2-sessions.c | 2 +-
> > include/linux/tpm.h | 37 +++++++++++++++++++++-----------
> > 3 files changed, 27 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
> > index 94231f052ea7..4a6a27ee295d 100644
> > --- a/drivers/char/tpm/tpm-sysfs.c
> > +++ b/drivers/char/tpm/tpm-sysfs.c
> > @@ -314,7 +314,7 @@ static ssize_t null_name_show(struct device *dev, struct device_attribute *attr,
> > char *buf)
> > {
> > struct tpm_chip *chip = to_tpm_chip(dev);
> > - int size = TPM2_NAME_SIZE;
> > + int size = TPM2_NULL_NAME_SIZE;
> >
> > bin2hex(buf, chip->null_key_name, size);
> > size *= 2;
> > diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c
> > index 4149379665c4..525b8622d1c3 100644
> > --- a/drivers/char/tpm/tpm2-sessions.c
> > +++ b/drivers/char/tpm/tpm2-sessions.c
> > @@ -137,7 +137,7 @@ struct tpm2_auth {
> > * we must compute and remember
> > */
> > u32 name_h[AUTH_MAX_NAMES];
> > - u8 name[AUTH_MAX_NAMES][2 + SHA512_DIGEST_SIZE];
> > + u8 name[AUTH_MAX_NAMES][TPM2_MAX_NAME_SIZE];
> > };
> >
> > #ifdef CONFIG_TCG_TPM2_HMAC
> > diff --git a/include/linux/tpm.h b/include/linux/tpm.h
> > index 202da079d500..e10f2096eae7 100644
> > --- a/include/linux/tpm.h
> > +++ b/include/linux/tpm.h
> > @@ -27,9 +27,33 @@
> >
> > #define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */
> >
> > +/*
> > + * SHA-512 is, as of today, the largest digest in the TCG algorithm repository.
> > + */
> > #define TPM2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
> > +
> > +/*
> > + * A TPM name digest i.e., TPMT_HA, is a concatenation of TPM_ALG_ID of the
> > + * name algorithm and hash of TPMT_PUBLIC.
> > + */
> > +#define TPM2_MAX_NAME_SIZE (TPM2_MAX_DIGEST_SIZE + 2)
> > +
> > +/*
> > + * The maximum number of PCR banks.
> > + */
> > #define TPM2_MAX_PCR_BANKS 8
> >
> > +/*
> > + * fixed define for the size of a name. This is actually HASHALG size
>
> "Fixed define".
Thanks, yeah, I can fix this up :-)
>
> > + * plus 2, so 32 for SHA256
> > + */
> > +#define TPM2_NULL_NAME_SIZE 34
> > +
> > +/*
> > + * The maximum size for an object context
> > + */
> > +#define TPM2_MAX_CONTEXT_SIZE 4096
> > +
> > struct tpm_chip;
> > struct trusted_key_payload;
> > struct trusted_key_options;
> > @@ -139,17 +163,6 @@ struct tpm_chip_seqops {
> > /* fixed define for the curve we use which is NIST_P256 */
> > #define EC_PT_SZ 32
> >
> > -/*
> > - * fixed define for the size of a name. This is actually HASHALG size
> > - * plus 2, so 32 for SHA256
> > - */
> > -#define TPM2_NAME_SIZE 34
> > -
> > -/*
> > - * The maximum size for an object context
> > - */
> > -#define TPM2_MAX_CONTEXT_SIZE 4096
> > -
> > struct tpm_chip {
> > struct device dev;
> > struct device devs;
> > @@ -211,7 +224,7 @@ struct tpm_chip {
> > /* saved context for NULL seed */
> > u8 null_key_context[TPM2_MAX_CONTEXT_SIZE];
> > /* name of NULL seed */
> > - u8 null_key_name[TPM2_NAME_SIZE];
> > + u8 null_key_name[TPM2_NULL_NAME_SIZE];
> > u8 null_ec_key_x[EC_PT_SZ];
> > u8 null_ec_key_y[EC_PT_SZ];
> > struct tpm2_auth *auth;
> > --
> > 2.39.5
> >
> >
>
> J.
>
> --
> Why do I get the feeling I'm going to regret this?
> This .sig brought to you by the letter S and the number 50
> Product of the Republic of HuggieTag
BR, Jarkko
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox