* [PATCH] keys: set persistent keyring timeout before destination linking
@ 2026-08-30 18:20 Karl Mehltretter
2026-09-01 13:30 ` Jarkko Sakkinen
0 siblings, 1 reply; 4+ messages in thread
From: Karl Mehltretter @ 2026-08-30 18:20 UTC (permalink / raw)
To: David Howells, Jarkko Sakkinen
Cc: Karl Mehltretter, Paul Moore, James Morris, Serge E. Hallyn,
keyrings, linux-security-module, linux-kernel
keyring_alloc() links a newly created persistent keyring into the
namespace's hidden register with TIME64_MAX expiry.
key_get_persistent() sets the configured timeout only after linking the
keyring into the caller's destination.
If the destination rejects the link, the registered keyring retains
infinite expiry. It is exempt from key quota and can remain until namespace
teardown or reboot even though the syscall returned an error. At most one
such keyring exists per UID per namespace. Repeated failures for the same
UID therefore strand only one small allocation.
This is reachable from unprivileged userspace: KEYCTL_RESTRICT_KEYRING on
the destination makes key_link() return -EPERM via restrict_link_reject(),
after key_create_persistent() has already registered the keyring.
Set the timeout immediately after creating and registering the keyring. A
later permission or destination-link failure then leaves a collectible
persistent keyring. The successful path may refresh the same timeout again
without changing its semantics.
Fixes: f36f8c75ae2e ("KEYS: Add per-user_namespace registers for persistent per-UID kerberos caches")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
Tested with QEMU 10.2.1 TCG. The reproducer set
/proc/sys/kernel/keys/persistent_keyring_expiry to 60 seconds, restricted
the destination with KEYCTL_RESTRICT_KEYRING, and then called
KEYCTL_GET_PERSISTENT. No LSM policy was loaded.
syscall result /proc/keys expiry
i386 baseline -EPERM perm
i386 patched -EPERM 1m
x86_64 patched -EPERM 1m
Full kernel builds completed for i386 and ARM926, and for x86_64 with
CONFIG_PROVE_LOCKING=y. The x86_64 reproducer completed without lockdep
reports, warnings, or bugs.
security/keys/persistent.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/security/keys/persistent.c b/security/keys/persistent.c
index 97af230aa4b22..0eca8c5758434 100644
--- a/security/keys/persistent.c
+++ b/security/keys/persistent.c
@@ -63,6 +63,12 @@ static key_ref_t key_create_persistent(struct user_namespace *ns, kuid_t uid,
if (IS_ERR(persistent))
return ERR_CAST(persistent);
+ /* Set the expiry now: if the caller then fails to link the keyring to
+ * its destination, the register is left holding a collectible key
+ * rather than a permanent, quota-exempt one.
+ */
+ key_set_timeout(persistent, persistent_keyring_expiry);
+
return make_key_ref(persistent, true);
}
base-commit: 08dbfad3f5040f5bdb6c529da20d6d4e81fefd72
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH] keys: set persistent keyring timeout before destination linking
2026-08-30 18:20 [PATCH] keys: set persistent keyring timeout before destination linking Karl Mehltretter
@ 2026-09-01 13:30 ` Jarkko Sakkinen
2026-09-01 16:16 ` Karl Mehltretter
0 siblings, 1 reply; 4+ messages in thread
From: Jarkko Sakkinen @ 2026-09-01 13:30 UTC (permalink / raw)
To: Karl Mehltretter
Cc: David Howells, Paul Moore, James Morris, Serge E. Hallyn,
keyrings, linux-security-module, linux-kernel
On Sun, Aug 30, 2026 at 08:20:26PM +0200, Karl Mehltretter wrote:
> keyring_alloc() links a newly created persistent keyring into the
> namespace's hidden register with TIME64_MAX expiry.
> key_get_persistent() sets the configured timeout only after linking the
> keyring into the caller's destination.
>
> If the destination rejects the link, the registered keyring retains
> infinite expiry. It is exempt from key quota and can remain until namespace
> teardown or reboot even though the syscall returned an error. At most one
> such keyring exists per UID per namespace. Repeated failures for the same
> UID therefore strand only one small allocation.
>
> This is reachable from unprivileged userspace: KEYCTL_RESTRICT_KEYRING on
> the destination makes key_link() return -EPERM via restrict_link_reject(),
> after key_create_persistent() has already registered the keyring.
>
> Set the timeout immediately after creating and registering the keyring. A
> later permission or destination-link failure then leaves a collectible
> persistent keyring. The successful path may refresh the same timeout again
> without changing its semantics.
>
> Fixes: f36f8c75ae2e ("KEYS: Add per-user_namespace registers for persistent per-UID kerberos caches")
> Assisted-by: LLM
> Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
> ---
> Tested with QEMU 10.2.1 TCG. The reproducer set
> /proc/sys/kernel/keys/persistent_keyring_expiry to 60 seconds, restricted
> the destination with KEYCTL_RESTRICT_KEYRING, and then called
> KEYCTL_GET_PERSISTENT. No LSM policy was loaded.
>
> syscall result /proc/keys expiry
> i386 baseline -EPERM perm
> i386 patched -EPERM 1m
> x86_64 patched -EPERM 1m
>
> Full kernel builds completed for i386 and ARM926, and for x86_64 with
> CONFIG_PROVE_LOCKING=y. The x86_64 reproducer completed without lockdep
> reports, warnings, or bugs.
Please describe this in the commit message and delete most of
the text it has. This is the motivation part.
>
> security/keys/persistent.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/security/keys/persistent.c b/security/keys/persistent.c
> index 97af230aa4b22..0eca8c5758434 100644
> --- a/security/keys/persistent.c
> +++ b/security/keys/persistent.c
> @@ -63,6 +63,12 @@ static key_ref_t key_create_persistent(struct user_namespace *ns, kuid_t uid,
> if (IS_ERR(persistent))
> return ERR_CAST(persistent);
>
> + /* Set the expiry now: if the caller then fails to link the keyring to
> + * its destination, the register is left holding a collectible key
> + * rather than a permanent, quota-exempt one.
> + */
> + key_set_timeout(persistent, persistent_keyring_expiry);
> +
> return make_key_ref(persistent, true);
> }
>
>
> base-commit: 08dbfad3f5040f5bdb6c529da20d6d4e81fefd72
> --
> 2.53.0
BR, Jarkko
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] keys: set persistent keyring timeout before destination linking
2026-09-01 13:30 ` Jarkko Sakkinen
@ 2026-09-01 16:16 ` Karl Mehltretter
2026-09-01 17:03 ` Jarkko Sakkinen
0 siblings, 1 reply; 4+ messages in thread
From: Karl Mehltretter @ 2026-09-01 16:16 UTC (permalink / raw)
To: Jarkko Sakkinen
Cc: David Howells, Paul Moore, James Morris, Serge E. Hallyn,
keyrings, linux-security-module, linux-kernel
On Tue, Sep 01, 2026 at 04:30:27PM +0100, Jarkko Sakkinen wrote:
> > Tested with QEMU 10.2.1 TCG. The reproducer set
> > /proc/sys/kernel/keys/persistent_keyring_expiry to 60 seconds, restricted
> > the destination with KEYCTL_RESTRICT_KEYRING, and then called
> > KEYCTL_GET_PERSISTENT. No LSM policy was loaded.
> >
> > syscall result /proc/keys expiry
> > i386 baseline -EPERM perm
> > i386 patched -EPERM 1m
> > x86_64 patched -EPERM 1m
> >
> > Full kernel builds completed for i386 and ARM926, and for x86_64 with
> > CONFIG_PROVE_LOCKING=y. The x86_64 reproducer completed without lockdep
> > reports, warnings, or bugs.
>
> Please describe this in the commit message and delete most of
> the text it has. This is the motivation part.
Got it, thanks. I'll shorten commit message.
I also found a narrow race if linking is delayed past expiry and GC runs.
It is unlikely in practice, but reproducible with an injected delay, so
I'll address it in v2.
Thanks,
Karl
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] keys: set persistent keyring timeout before destination linking
2026-09-01 16:16 ` Karl Mehltretter
@ 2026-09-01 17:03 ` Jarkko Sakkinen
0 siblings, 0 replies; 4+ messages in thread
From: Jarkko Sakkinen @ 2026-09-01 17:03 UTC (permalink / raw)
To: Karl Mehltretter
Cc: David Howells, Paul Moore, James Morris, Serge E. Hallyn,
keyrings, linux-security-module, linux-kernel
On Tue, Sep 01, 2026 at 06:16:12PM +0200, Karl Mehltretter wrote:
> On Tue, Sep 01, 2026 at 04:30:27PM +0100, Jarkko Sakkinen wrote:
> > > Tested with QEMU 10.2.1 TCG. The reproducer set
> > > /proc/sys/kernel/keys/persistent_keyring_expiry to 60 seconds, restricted
> > > the destination with KEYCTL_RESTRICT_KEYRING, and then called
> > > KEYCTL_GET_PERSISTENT. No LSM policy was loaded.
> > >
> > > syscall result /proc/keys expiry
> > > i386 baseline -EPERM perm
> > > i386 patched -EPERM 1m
> > > x86_64 patched -EPERM 1m
> > >
> > > Full kernel builds completed for i386 and ARM926, and for x86_64 with
> > > CONFIG_PROVE_LOCKING=y. The x86_64 reproducer completed without lockdep
> > > reports, warnings, or bugs.
> >
> > Please describe this in the commit message and delete most of
> > the text it has. This is the motivation part.
>
> Got it, thanks. I'll shorten commit message.
>
> I also found a narrow race if linking is delayed past expiry and GC runs.
> It is unlikely in practice, but reproducible with an injected delay, so
> I'll address it in v2.
>
Yeah, I mean what say there is not secret as it is here already.
So better to document the relevant data to commit message. That is
what is useful for me as a maintainer fast-forward to the future.
While writing a commit message think more what makes sense to backtrack
in the future rather than writing a tutorial ;-)
> Thanks,
> Karl
BR, Jarkko
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-09-01 17:03 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-30 18:20 [PATCH] keys: set persistent keyring timeout before destination linking Karl Mehltretter
2026-09-01 13:30 ` Jarkko Sakkinen
2026-09-01 16:16 ` Karl Mehltretter
2026-09-01 17:03 ` Jarkko Sakkinen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox