mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 1/2] KEYS: Return user session keyring on lookup
@ 2026-10-19 14:56 Jarkko Sakkinen
  2026-10-19 14:56 ` [PATCH v2 2/2] KEYS: Reject keyring creation with overridden credentials Jarkko Sakkinen
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Jarkko Sakkinen @ 2026-10-19 14:56 UTC (permalink / raw)
  To: David Howells
  Cc: keyrings, Eric Biggers, Jarkko Sakkinen, stable, Jann Horn,
	Jonathan Corbet, Shuah Khan, Randy Dunlap, Paul Moore,
	James Morris, Serge E. Hallyn, open list:DOCUMENTATION,
	open list, open list:SECURITY SUBSYSTEM

A process without a session keyring looking up KEY_SPEC_SESSION_KEYRING
without KEY_LOOKUP_CREATE mutates the credentials. This causes struct creds
instances shared with other subsystems to become stale.

Address this by returning the resolved user session keyring directly
without installing it into credentials.

Cc: stable@vger.kernel.org # v5.10+
Suggested-by: Jann Horn <jannh@google.com>
Closes: https://lore.kernel.org/keyrings/CAG48ez0XjVSR=M--UBauTm8sJuc+ZbhKzaPa3a6wrSVHyoKevw@mail.gmail.com/
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
---
v2:
- Added mandatory tags.
- No code changes.
---
 Documentation/security/keys/core.rst |  6 ++--
 security/keys/process_keys.c         | 44 +++++++---------------------
 2 files changed, 14 insertions(+), 36 deletions(-)

diff --git a/Documentation/security/keys/core.rst b/Documentation/security/keys/core.rst
index 326b8a973828..c81a3a9fe236 100644
--- a/Documentation/security/keys/core.rst
+++ b/Documentation/security/keys/core.rst
@@ -165,8 +165,10 @@ The key service provides a number of features besides keys:
      When a process changes its real UID, if it used to have no session key, it
      will be subscribed to the default session key for the new UID.
 
-     If a process attempts to access its session key when it doesn't have one,
-     it will be subscribed to the default for its current UID.
+     If a process attempts to access its session keyring when it doesn't have
+     one, the default user session keyring for its current UID is returned
+     without being installed into its credentials.  If creation is requested,
+     an anonymous session keyring is installed.
 
   *  Each user has two quotas against which the keys they own are tracked. One
      limits the total number of keys and keyrings, the other limits the total
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 1a51a36ce32a..558ffe58b5d6 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -346,31 +346,6 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
 	return 0;
 }
 
-/*
- * Install the given keyring as the session keyring of the current task,
- * replacing the existing one if any.  If the given keyring is NULL, then
- * install a new anonymous session keyring.
- *
- * Return: 0 on success; -errno on failure.
- */
-static int install_session_keyring(struct key *keyring)
-{
-	struct cred *new;
-	int ret;
-
-	new = prepare_creds();
-	if (!new)
-		return -ENOMEM;
-
-	ret = install_session_keyring_to_cred(new, keyring);
-	if (ret < 0) {
-		abort_creds(new);
-		return ret;
-	}
-
-	return commit_creds(new);
-}
-
 /*
  * Handle the fsuid changing.
  */
@@ -664,20 +639,21 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
 
 	case KEY_SPEC_SESSION_KEYRING:
 		if (!ctx.cred->session_keyring) {
-			/* always install a session keyring upon access if one
-			 * doesn't exist yet */
 			ret = look_up_user_keyrings(NULL, &user_session);
 			if (ret < 0)
 				goto error;
-			if (lflags & KEY_LOOKUP_CREATE)
+
+			if (lflags & KEY_LOOKUP_CREATE) {
+				key_put(user_session);
 				ret = join_session_keyring(NULL);
-			else
-				ret = install_session_keyring(user_session);
+				if (ret < 0)
+					goto error;
+				goto reget_creds;
+			}
 
-			key_put(user_session);
-			if (ret < 0)
-				goto error;
-			goto reget_creds;
+			key = user_session;
+			key_ref = make_key_ref(key, 1);
+			break;
 		} else if (test_bit(KEY_FLAG_UID_KEYRING,
 				    &ctx.cred->session_keyring->flags) &&
 			   lflags & KEY_LOOKUP_CREATE) {
-- 
2.47.3


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 2/2] KEYS: Reject keyring creation with overridden credentials
  2026-10-19 14:56 [PATCH v2 1/2] KEYS: Return user session keyring on lookup Jarkko Sakkinen
@ 2026-10-19 14:56 ` Jarkko Sakkinen
  2026-10-19 15:59 ` David Howells
  2026-10-21  8:20 ` [syzbot ci] Re: KEYS: Return user session keyring on lookup syzbot ci
  2 siblings, 0 replies; 5+ messages in thread
From: Jarkko Sakkinen @ 2026-10-19 14:56 UTC (permalink / raw)
  To: David Howells
  Cc: keyrings, Eric Biggers, Jarkko Sakkinen, stable, Jann Horn,
	Jonathan Corbet, Shuah Khan, Randy Dunlap, Paul Moore,
	James Morris, Serge E. Hallyn, open list:DOCUMENTATION,
	open list, open list:SECURITY SUBSYSTEM

If the current task is running with overridden credentials calling
commit_creds() is forbidden and triggers a BUG_ON().

Reject keyring creation with -EPERM when credentials are overridden.

Cc: stable@vger.kernel.org # v5.10+
Suggested-by: Jann Horn <jannh@google.com>
Closes: https://lore.kernel.org/keyrings/CAG48ez0XjVSR=M--UBauTm8sJuc+ZbhKzaPa3a6wrSVHyoKevw@mail.gmail.com/
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
---
v2:
- Added mandatory tags.
- No code changes.
---
 Documentation/security/keys/core.rst |  3 ++-
 security/keys/process_keys.c         | 31 +++++++++++++++++++++++++++-
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/Documentation/security/keys/core.rst b/Documentation/security/keys/core.rst
index c81a3a9fe236..9779ce71df47 100644
--- a/Documentation/security/keys/core.rst
+++ b/Documentation/security/keys/core.rst
@@ -168,7 +168,8 @@ The key service provides a number of features besides keys:
      If a process attempts to access its session keyring when it doesn't have
      one, the default user session keyring for its current UID is returned
      without being installed into its credentials.  If creation is requested,
-     an anonymous session keyring is installed.
+     an anonymous session keyring is installed, failing with -EPERM if
+     credentials are overridden.
 
   *  Each user has two quotas against which the keys they own are tracked. One
      limits the total number of keys and keyrings, the other limits the total
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 558ffe58b5d6..ab7f13ccebb1 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -346,6 +346,14 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
 	return 0;
 }
 
+/*
+ * Determine whether the current task is running with overridden credentials.
+ */
+static bool cred_overridden(void)
+{
+	return current_cred() != current_real_cred();
+}
+
 /*
  * Handle the fsuid changing.
  */
@@ -577,7 +585,8 @@ bool lookup_user_key_possessed(const struct key *key,
  * to a key or the best found key was a negative key; -EKEYREVOKED or
  * -EKEYEXPIRED if the best found key was revoked or expired; -EACCES if the
  * found key doesn't grant the requested permit or the LSM denied access to it;
- * or -ENOMEM if a special keyring couldn't be created.
+ * -ENOMEM if a special keyring couldn't be created; or -EPERM if creating one
+ * while credentials are overridden.
  *
  * In the case of a successful return, the possession attribute is set on the
  * returned key reference.
@@ -606,6 +615,11 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
 			if (!(lflags & KEY_LOOKUP_CREATE))
 				goto error;
 
+			if (cred_overridden()) {
+				key_ref = ERR_PTR(-EPERM);
+				goto error;
+			}
+
 			ret = install_thread_keyring();
 			if (ret < 0) {
 				key_ref = ERR_PTR(ret);
@@ -624,6 +638,11 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
 			if (!(lflags & KEY_LOOKUP_CREATE))
 				goto error;
 
+			if (cred_overridden()) {
+				key_ref = ERR_PTR(-EPERM);
+				goto error;
+			}
+
 			ret = install_process_keyring();
 			if (ret < 0) {
 				key_ref = ERR_PTR(ret);
@@ -645,6 +664,11 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
 
 			if (lflags & KEY_LOOKUP_CREATE) {
 				key_put(user_session);
+				if (cred_overridden()) {
+					key_ref = ERR_PTR(-EPERM);
+					goto error;
+				}
+
 				ret = join_session_keyring(NULL);
 				if (ret < 0)
 					goto error;
@@ -657,6 +681,11 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
 		} else if (test_bit(KEY_FLAG_UID_KEYRING,
 				    &ctx.cred->session_keyring->flags) &&
 			   lflags & KEY_LOOKUP_CREATE) {
+			if (cred_overridden()) {
+				key_ref = ERR_PTR(-EPERM);
+				goto error;
+			}
+
 			ret = join_session_keyring(NULL);
 			if (ret < 0)
 				goto error;
-- 
2.47.3


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 2/2] KEYS: Reject keyring creation with overridden credentials
  2026-10-19 14:56 [PATCH v2 1/2] KEYS: Return user session keyring on lookup Jarkko Sakkinen
  2026-10-19 14:56 ` [PATCH v2 2/2] KEYS: Reject keyring creation with overridden credentials Jarkko Sakkinen
@ 2026-10-19 15:59 ` David Howells
  2026-10-19 17:08   ` Jarkko Sakkinen
  2026-10-21  8:20 ` [syzbot ci] Re: KEYS: Return user session keyring on lookup syzbot ci
  2 siblings, 1 reply; 5+ messages in thread
From: David Howells @ 2026-10-19 15:59 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: dhowells, keyrings, Eric Biggers, stable, Jann Horn,
	Jonathan Corbet, Shuah Khan, Randy Dunlap, Paul Moore,
	James Morris, Serge E. Hallyn, open list:DOCUMENTATION,
	open list, open list:SECURITY SUBSYSTEM

Would it make sense to just reject KEY_LOOKUP_CREATE at the top of the
function if the creds are overridden?

David


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 2/2] KEYS: Reject keyring creation with overridden credentials
  2026-10-19 15:59 ` David Howells
@ 2026-10-19 17:08   ` Jarkko Sakkinen
  0 siblings, 0 replies; 5+ messages in thread
From: Jarkko Sakkinen @ 2026-10-19 17:08 UTC (permalink / raw)
  To: David Howells
  Cc: keyrings, Eric Biggers, stable, Jann Horn, Jonathan Corbet,
	Shuah Khan, Randy Dunlap, Paul Moore, James Morris,
	Serge E. Hallyn, open list:DOCUMENTATION, open list,
	open list:SECURITY SUBSYSTEM

On Mon, Oct 19, 2026 at 04:59:10PM +0100, David Howells wrote:
> Would it make sense to just reject KEY_LOOKUP_CREATE at the top of the
> function if the creds are overridden?

Let me check..

Yep, I suppose you're right. I'll update the patch.

> 
> David
> 

Br, Jarkko

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [syzbot ci] Re: KEYS: Return user session keyring on lookup
  2026-10-19 14:56 [PATCH v2 1/2] KEYS: Return user session keyring on lookup Jarkko Sakkinen
  2026-10-19 14:56 ` [PATCH v2 2/2] KEYS: Reject keyring creation with overridden credentials Jarkko Sakkinen
  2026-10-19 15:59 ` David Howells
@ 2026-10-21  8:20 ` syzbot ci
  2 siblings, 0 replies; 5+ messages in thread
From: syzbot ci @ 2026-10-21  8:20 UTC (permalink / raw)
  To: corbet, dhowells, ebiggers, jannh, jarkko, jmorris, keyrings,
	linux-doc, linux-kernel, linux-security-module, paul, rdunlap,
	serge, skhan, stable
  Cc: syzbot, syzkaller-bugs

syzbot ci has tested the following series

[v2] KEYS: Return user session keyring on lookup
https://lore.kernel.org/all/20261019145624.309790-1-jarkko@kernel.org
* [PATCH v2 1/2] KEYS: Return user session keyring on lookup
* [PATCH v2 2/2] KEYS: Reject keyring creation with overridden credentials

and found the following issue:
general protection fault in keyctl_session_to_parent

Full report is available here:
https://ci.syzbot.org/series/7566814a-52ba-4f0b-b506-d7adf67fda29

***

general protection fault in keyctl_session_to_parent

tree:      linux-next
URL:       https://kernel.googlesource.com/pub/scm/linux/kernel/git/next/linux-next
base:      17a7501b9612a52b38bc57e33c7b64636d438bc0
arch:      amd64
compiler:  Debian clang version 22.1.8 (1~deb13u4), Debian LLD 22.1.8
config:    https://ci.syzbot.org/builds/eee373c7-f447-49cf-a350-83830580c7b2/config

Oops: general protection fault, probably for non-canonical address 0xdffffc000000001b: 0000 [#1] SMP KASAN PTI
KASAN: null-ptr-deref in range [0x00000000000000d8-0x00000000000000df]
CPU: 0 UID: 0 PID: 5730 Comm: syz.0.6 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
RIP: 0010:keyctl_session_to_parent+0x825/0xa30
Code: 35 3b fd e9 fe fa ff ff e8 38 35 3b fd e9 f4 fa ff ff e8 2e 35 3b fd 48 8b 54 24 20 48 81 c2 d8 00 00 00 48 89 d0 48 c1 e8 03 <0f> b6 04 18 84 c0 0f 85 b2 01 00 00 8b 2a 89 ef 8b 5c 24 1c 89 de
RSP: 0018:ffffc9000621fc70 EFLAGS: 00010006
RAX: 000000000000001b RBX: dffffc0000000000 RCX: ffff88810b603c00
RDX: 00000000000000d8 RSI: 0000000000000000 RDI: 0000000000000000
RBP: 0000000000000000 R08: 0000000000000003 R09: 0000000000000004
R10: dffffc0000000000 R11: fffff52000c43f7c R12: ffff88811a010000
R13: 0000000000000000 R14: ffff88810c2631a8 R15: 0000000000000000
FS:  00007f7f2068b6c0(0000) GS:ffff88818c4bf000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f7f2068aff8 CR3: 000000010cae8000 CR4: 00000000000006f0
Call Trace:
 <TASK>
 __se_sys_keyctl+0x780/0x9d0
 do_syscall_64+0x166/0x520
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f7f1f79f559
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f7f2068b028 EFLAGS: 00000246 ORIG_RAX: 00000000000000fa
RAX: ffffffffffffffda RBX: 00007f7f1fa26270 RCX: 00007f7f1f79f559
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000012
RBP: 00007f7f1f836b20 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f7f1fa26308 R14: 00007f7f1fa26270 R15: 00007ffe789f59b8
 </TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:keyctl_session_to_parent+0x825/0xa30
Code: 35 3b fd e9 fe fa ff ff e8 38 35 3b fd e9 f4 fa ff ff e8 2e 35 3b fd 48 8b 54 24 20 48 81 c2 d8 00 00 00 48 89 d0 48 c1 e8 03 <0f> b6 04 18 84 c0 0f 85 b2 01 00 00 8b 2a 89 ef 8b 5c 24 1c 89 de
RSP: 0018:ffffc9000621fc70 EFLAGS: 00010006
RAX: 000000000000001b RBX: dffffc0000000000 RCX: ffff88810b603c00
RDX: 00000000000000d8 RSI: 0000000000000000 RDI: 0000000000000000
RBP: 0000000000000000 R08: 0000000000000003 R09: 0000000000000004
R10: dffffc0000000000 R11: fffff52000c43f7c R12: ffff88811a010000
R13: 0000000000000000 R14: ffff88810c2631a8 R15: 0000000000000000
FS:  00007f7f2068b6c0(0000) GS:ffff88818c4bf000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f7f2068aff8 CR3: 000000010cae8000 CR4: 00000000000006f0


***

If these findings have caused you to resend the series or submit a
separate fix, please add the following tag to your commit message:
  Tested-by: syzbot@syzkaller.appspotmail.com

---
This report is generated by a bot. It may contain errors.
syzbot ci engineers can be reached at syzkaller@googlegroups.com.

To test a fix for this bug, please reply with `#syz test`
(on a separate line) and attach the patch to the email.

Notes:
- The patch will be applied on top of the tested series (as an
  incremental fix).
- To test a new version of the whole series, please send it directly
  to syzbot@lists.linux.dev.
- Arguments like custom git repos and branches are not supported.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-10-21  8:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-19 14:56 [PATCH v2 1/2] KEYS: Return user session keyring on lookup Jarkko Sakkinen
2026-10-19 14:56 ` [PATCH v2 2/2] KEYS: Reject keyring creation with overridden credentials Jarkko Sakkinen
2026-10-19 15:59 ` David Howells
2026-10-19 17:08   ` Jarkko Sakkinen
2026-10-21  8:20 ` [syzbot ci] Re: KEYS: Return user session keyring on lookup syzbot ci

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®