* [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access()
@ 2024-07-29 12:58 Mickaël Salaün
2024-07-29 13:49 ` Jann Horn
2024-07-29 14:06 ` Jarkko Sakkinen
0 siblings, 2 replies; 14+ messages in thread
From: Mickaël Salaün @ 2024-07-29 12:58 UTC (permalink / raw)
To: David Howells, Jarkko Sakkinen
Cc: Mickaël Salaün, Günther Noack, James Morris,
Jann Horn, Kees Cook, Paul Moore, keyrings, linux-kernel,
linux-security-module
A process can modify its parent's credentials with
KEYCTL_SESSION_TO_PARENT when their EUID and EGID are the same. This
doesn't take into account all possible access controls.
Enforce the same access checks as for impersonating a process.
The current credentials checks are untouch because they check against
EUID and EGID, whereas ptrace_may_access() checks against UID and GID.
Cc: David Howells <dhowells@redhat.com>
Cc: Günther Noack <gnoack@google.com>
Cc: James Morris <jmorris@namei.org>
Cc: Jann Horn <jannh@google.com>
Cc: Jarkko Sakkinen <jarkko@kernel.org>
Cc: Kees Cook <kees@kernel.org>
Cc: Paul Moore <paul@paul-moore.com>
Fixes: ee18d64c1f63 ("KEYS: Add a keyctl to install a process's session keyring on its parent [try #6]")
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20240729125846.1043211-1-mic@digikod.net
---
security/keys/keyctl.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index ab927a142f51..511bf79fa14c 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -21,6 +21,7 @@
#include <linux/security.h>
#include <linux/uio.h>
#include <linux/uaccess.h>
+#include <linux/ptrace.h>
#include <keys/request_key_auth-type.h>
#include "internal.h"
@@ -1687,6 +1688,10 @@ long keyctl_session_to_parent(void)
!gid_eq(pcred->sgid, mycred->egid))
goto unlock;
+ /* The child must be allowed to impersonate its parent process. */
+ if (!ptrace_may_access(parent, PTRACE_MODE_ATTACH_REALCREDS))
+ goto unlock;
+
/* the keyrings must have the same UID */
if ((pcred->session_keyring &&
!uid_eq(pcred->session_keyring->uid, mycred->euid)) ||
base-commit: 8400291e289ee6b2bf9779ff1c83a291501f017b
--
2.45.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access() 2024-07-29 12:58 [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access() Mickaël Salaün @ 2024-07-29 13:49 ` Jann Horn 2024-07-29 14:09 ` Mickaël Salaün 2024-07-29 14:06 ` Jarkko Sakkinen 1 sibling, 1 reply; 14+ messages in thread From: Jann Horn @ 2024-07-29 13:49 UTC (permalink / raw) To: Mickaël Salaün Cc: David Howells, Jarkko Sakkinen, Günther Noack, James Morris, Kees Cook, Paul Moore, keyrings, linux-kernel, linux-security-module On Mon, Jul 29, 2024 at 2:59 PM Mickaël Salaün <mic@digikod.net> wrote: > A process can modify its parent's credentials with > KEYCTL_SESSION_TO_PARENT when their EUID and EGID are the same. This > doesn't take into account all possible access controls. > > Enforce the same access checks as for impersonating a process. > > The current credentials checks are untouch because they check against > EUID and EGID, whereas ptrace_may_access() checks against UID and GID. FWIW, my understanding is that the intended usecase of KEYCTL_SESSION_TO_PARENT is that command-line tools (like "keyctl new_session" and "e4crypt new_session") want to be able to change the keyring of the parent process that spawned them (which I think is usually a shell?); and Yama LSM, which I think is fairly widely used at this point, by default prevents a child process from using PTRACE_MODE_ATTACH on its parent. I think KEYCTL_SESSION_TO_PARENT is not a great design, but I'm not sure if we can improve it much without risking some breakage. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access() 2024-07-29 13:49 ` Jann Horn @ 2024-07-29 14:09 ` Mickaël Salaün 2024-07-29 14:21 ` Jann Horn 0 siblings, 1 reply; 14+ messages in thread From: Mickaël Salaün @ 2024-07-29 14:09 UTC (permalink / raw) To: Jann Horn Cc: David Howells, Jarkko Sakkinen, Günther Noack, James Morris, Kees Cook, Paul Moore, keyrings, linux-kernel, linux-security-module On Mon, Jul 29, 2024 at 03:49:29PM +0200, Jann Horn wrote: > On Mon, Jul 29, 2024 at 2:59 PM Mickaël Salaün <mic@digikod.net> wrote: > > A process can modify its parent's credentials with > > KEYCTL_SESSION_TO_PARENT when their EUID and EGID are the same. This > > doesn't take into account all possible access controls. > > > > Enforce the same access checks as for impersonating a process. > > > > The current credentials checks are untouch because they check against > > EUID and EGID, whereas ptrace_may_access() checks against UID and GID. > > FWIW, my understanding is that the intended usecase of > KEYCTL_SESSION_TO_PARENT is that command-line tools (like "keyctl > new_session" and "e4crypt new_session") want to be able to change the > keyring of the parent process that spawned them (which I think is > usually a shell?); and Yama LSM, which I think is fairly widely used > at this point, by default prevents a child process from using > PTRACE_MODE_ATTACH on its parent. About Yama, the patched keyctl_session_to_parent() function already check if the current's and the parent's credentials are the same before this new ptrace_may_access() check. So this change should be OK with Yama and most use cases. > > I think KEYCTL_SESSION_TO_PARENT is not a great design, but I'm not > sure if we can improve it much without risking some breakage. > I think this is a security issue that a process can change another process's credentials. If the main use cases is for shell commands, it should be OK. The alternative would be to restore the key_session_to_parent LSM hook [1], and update most LSMs to block this kind of credential tampering, which will lead to the same result but with only partial users being protected. [1] commit 3011a344cdcd ("security: remove dead hook key_session_to_parent") ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access() 2024-07-29 14:09 ` Mickaël Salaün @ 2024-07-29 14:21 ` Jann Horn 2024-07-29 15:02 ` Mickaël Salaün 0 siblings, 1 reply; 14+ messages in thread From: Jann Horn @ 2024-07-29 14:21 UTC (permalink / raw) To: Mickaël Salaün Cc: David Howells, Jarkko Sakkinen, Günther Noack, James Morris, Kees Cook, Paul Moore, keyrings, linux-kernel, linux-security-module On Mon, Jul 29, 2024 at 4:09 PM Mickaël Salaün <mic@digikod.net> wrote: > On Mon, Jul 29, 2024 at 03:49:29PM +0200, Jann Horn wrote: > > On Mon, Jul 29, 2024 at 2:59 PM Mickaël Salaün <mic@digikod.net> wrote: > > > A process can modify its parent's credentials with > > > KEYCTL_SESSION_TO_PARENT when their EUID and EGID are the same. This > > > doesn't take into account all possible access controls. > > > > > > Enforce the same access checks as for impersonating a process. > > > > > > The current credentials checks are untouch because they check against > > > EUID and EGID, whereas ptrace_may_access() checks against UID and GID. > > > > FWIW, my understanding is that the intended usecase of > > KEYCTL_SESSION_TO_PARENT is that command-line tools (like "keyctl > > new_session" and "e4crypt new_session") want to be able to change the > > keyring of the parent process that spawned them (which I think is > > usually a shell?); and Yama LSM, which I think is fairly widely used > > at this point, by default prevents a child process from using > > PTRACE_MODE_ATTACH on its parent. > > About Yama, the patched keyctl_session_to_parent() function already > check if the current's and the parent's credentials are the same before > this new ptrace_may_access() check. prepare_exec_creds() in execve() always creates new credentials which are stored in bprm->cred and then later committed in begin_new_exec(). Also, fork() always copies the credentials in copy_creds(). So the "mycred == pcred" condition in keyctl_session_to_parent() basically never applies, I think. Also: When that condition is true, the whole operation is a no-op, since if the credentials are the same, then the session keyring that the credentials point to must also be the same. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access() 2024-07-29 14:21 ` Jann Horn @ 2024-07-29 15:02 ` Mickaël Salaün 2024-07-29 15:06 ` Jann Horn 0 siblings, 1 reply; 14+ messages in thread From: Mickaël Salaün @ 2024-07-29 15:02 UTC (permalink / raw) To: Jann Horn Cc: David Howells, Jarkko Sakkinen, Günther Noack, James Morris, Kees Cook, Paul Moore, keyrings, linux-kernel, linux-security-module On Mon, Jul 29, 2024 at 04:21:01PM +0200, Jann Horn wrote: > On Mon, Jul 29, 2024 at 4:09 PM Mickaël Salaün <mic@digikod.net> wrote: > > On Mon, Jul 29, 2024 at 03:49:29PM +0200, Jann Horn wrote: > > > On Mon, Jul 29, 2024 at 2:59 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > A process can modify its parent's credentials with > > > > KEYCTL_SESSION_TO_PARENT when their EUID and EGID are the same. This > > > > doesn't take into account all possible access controls. > > > > > > > > Enforce the same access checks as for impersonating a process. > > > > > > > > The current credentials checks are untouch because they check against > > > > EUID and EGID, whereas ptrace_may_access() checks against UID and GID. > > > > > > FWIW, my understanding is that the intended usecase of > > > KEYCTL_SESSION_TO_PARENT is that command-line tools (like "keyctl > > > new_session" and "e4crypt new_session") want to be able to change the > > > keyring of the parent process that spawned them (which I think is > > > usually a shell?); and Yama LSM, which I think is fairly widely used > > > at this point, by default prevents a child process from using > > > PTRACE_MODE_ATTACH on its parent. > > > > About Yama, the patched keyctl_session_to_parent() function already > > check if the current's and the parent's credentials are the same before > > this new ptrace_may_access() check. > > prepare_exec_creds() in execve() always creates new credentials which > are stored in bprm->cred and then later committed in begin_new_exec(). > Also, fork() always copies the credentials in copy_creds(). > So the "mycred == pcred" condition in keyctl_session_to_parent() > basically never applies, I think. > Also: When that condition is true, the whole operation is a no-op, > since if the credentials are the same, then the session keyring that > the credentials point to must also be the same. Correct, it's not a content comparison. We could compare the credential's data for this specific KEYCTL_SESSION_TO_PARENT call, I guess this should not be performance sensitive. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access() 2024-07-29 15:02 ` Mickaël Salaün @ 2024-07-29 15:06 ` Jann Horn 2024-07-29 15:17 ` Mickaël Salaün 0 siblings, 1 reply; 14+ messages in thread From: Jann Horn @ 2024-07-29 15:06 UTC (permalink / raw) To: Mickaël Salaün Cc: David Howells, Jarkko Sakkinen, Günther Noack, James Morris, Kees Cook, Paul Moore, keyrings, linux-kernel, linux-security-module On Mon, Jul 29, 2024 at 5:02 PM Mickaël Salaün <mic@digikod.net> wrote: > On Mon, Jul 29, 2024 at 04:21:01PM +0200, Jann Horn wrote: > > On Mon, Jul 29, 2024 at 4:09 PM Mickaël Salaün <mic@digikod.net> wrote: > > > On Mon, Jul 29, 2024 at 03:49:29PM +0200, Jann Horn wrote: > > > > On Mon, Jul 29, 2024 at 2:59 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > > A process can modify its parent's credentials with > > > > > KEYCTL_SESSION_TO_PARENT when their EUID and EGID are the same. This > > > > > doesn't take into account all possible access controls. > > > > > > > > > > Enforce the same access checks as for impersonating a process. > > > > > > > > > > The current credentials checks are untouch because they check against > > > > > EUID and EGID, whereas ptrace_may_access() checks against UID and GID. > > > > > > > > FWIW, my understanding is that the intended usecase of > > > > KEYCTL_SESSION_TO_PARENT is that command-line tools (like "keyctl > > > > new_session" and "e4crypt new_session") want to be able to change the > > > > keyring of the parent process that spawned them (which I think is > > > > usually a shell?); and Yama LSM, which I think is fairly widely used > > > > at this point, by default prevents a child process from using > > > > PTRACE_MODE_ATTACH on its parent. > > > > > > About Yama, the patched keyctl_session_to_parent() function already > > > check if the current's and the parent's credentials are the same before > > > this new ptrace_may_access() check. > > > > prepare_exec_creds() in execve() always creates new credentials which > > are stored in bprm->cred and then later committed in begin_new_exec(). > > Also, fork() always copies the credentials in copy_creds(). > > So the "mycred == pcred" condition in keyctl_session_to_parent() > > basically never applies, I think. > > Also: When that condition is true, the whole operation is a no-op, > > since if the credentials are the same, then the session keyring that > > the credentials point to must also be the same. > > Correct, it's not a content comparison. We could compare the > credential's data for this specific KEYCTL_SESSION_TO_PARENT call, I > guess this should not be performance sensitive. Yeah, though I guess keyctl_session_to_parent() is already kind of doing that for the UID information; and for LSMs that would mean adding an extra LSM hook? ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access() 2024-07-29 15:06 ` Jann Horn @ 2024-07-29 15:17 ` Mickaël Salaün 2024-07-31 20:29 ` Paul Moore 0 siblings, 1 reply; 14+ messages in thread From: Mickaël Salaün @ 2024-07-29 15:17 UTC (permalink / raw) To: Jann Horn Cc: David Howells, Jarkko Sakkinen, Günther Noack, James Morris, Kees Cook, Paul Moore, keyrings, linux-kernel, linux-security-module On Mon, Jul 29, 2024 at 05:06:10PM +0200, Jann Horn wrote: > On Mon, Jul 29, 2024 at 5:02 PM Mickaël Salaün <mic@digikod.net> wrote: > > On Mon, Jul 29, 2024 at 04:21:01PM +0200, Jann Horn wrote: > > > On Mon, Jul 29, 2024 at 4:09 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > On Mon, Jul 29, 2024 at 03:49:29PM +0200, Jann Horn wrote: > > > > > On Mon, Jul 29, 2024 at 2:59 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > > > A process can modify its parent's credentials with > > > > > > KEYCTL_SESSION_TO_PARENT when their EUID and EGID are the same. This > > > > > > doesn't take into account all possible access controls. > > > > > > > > > > > > Enforce the same access checks as for impersonating a process. > > > > > > > > > > > > The current credentials checks are untouch because they check against > > > > > > EUID and EGID, whereas ptrace_may_access() checks against UID and GID. > > > > > > > > > > FWIW, my understanding is that the intended usecase of > > > > > KEYCTL_SESSION_TO_PARENT is that command-line tools (like "keyctl > > > > > new_session" and "e4crypt new_session") want to be able to change the > > > > > keyring of the parent process that spawned them (which I think is > > > > > usually a shell?); and Yama LSM, which I think is fairly widely used > > > > > at this point, by default prevents a child process from using > > > > > PTRACE_MODE_ATTACH on its parent. > > > > > > > > About Yama, the patched keyctl_session_to_parent() function already > > > > check if the current's and the parent's credentials are the same before > > > > this new ptrace_may_access() check. > > > > > > prepare_exec_creds() in execve() always creates new credentials which > > > are stored in bprm->cred and then later committed in begin_new_exec(). > > > Also, fork() always copies the credentials in copy_creds(). > > > So the "mycred == pcred" condition in keyctl_session_to_parent() > > > basically never applies, I think. > > > Also: When that condition is true, the whole operation is a no-op, > > > since if the credentials are the same, then the session keyring that > > > the credentials point to must also be the same. > > > > Correct, it's not a content comparison. We could compare the > > credential's data for this specific KEYCTL_SESSION_TO_PARENT call, I > > guess this should not be performance sensitive. > > Yeah, though I guess keyctl_session_to_parent() is already kind of > doing that for the UID information; and for LSMs that would mean > adding an extra LSM hook? I'm wondering why security_key_session_to_parent() was never used: see commit 3011a344cdcd ("security: remove dead hook key_session_to_parent") ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access() 2024-07-29 15:17 ` Mickaël Salaün @ 2024-07-31 20:29 ` Paul Moore 2024-07-31 20:53 ` Jann Horn 0 siblings, 1 reply; 14+ messages in thread From: Paul Moore @ 2024-07-31 20:29 UTC (permalink / raw) To: Mickaël Salaün Cc: Jann Horn, David Howells, Jarkko Sakkinen, Günther Noack, James Morris, Kees Cook, keyrings, linux-kernel, linux-security-module On Mon, Jul 29, 2024 at 11:17 AM Mickaël Salaün <mic@digikod.net> wrote: > On Mon, Jul 29, 2024 at 05:06:10PM +0200, Jann Horn wrote: > > On Mon, Jul 29, 2024 at 5:02 PM Mickaël Salaün <mic@digikod.net> wrote: > > > On Mon, Jul 29, 2024 at 04:21:01PM +0200, Jann Horn wrote: > > > > On Mon, Jul 29, 2024 at 4:09 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > > On Mon, Jul 29, 2024 at 03:49:29PM +0200, Jann Horn wrote: > > > > > > On Mon, Jul 29, 2024 at 2:59 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > > > > A process can modify its parent's credentials with > > > > > > > KEYCTL_SESSION_TO_PARENT when their EUID and EGID are the same. This > > > > > > > doesn't take into account all possible access controls. > > > > > > > > > > > > > > Enforce the same access checks as for impersonating a process. > > > > > > > > > > > > > > The current credentials checks are untouch because they check against > > > > > > > EUID and EGID, whereas ptrace_may_access() checks against UID and GID. > > > > > > > > > > > > FWIW, my understanding is that the intended usecase of > > > > > > KEYCTL_SESSION_TO_PARENT is that command-line tools (like "keyctl > > > > > > new_session" and "e4crypt new_session") want to be able to change the > > > > > > keyring of the parent process that spawned them (which I think is > > > > > > usually a shell?); and Yama LSM, which I think is fairly widely used > > > > > > at this point, by default prevents a child process from using > > > > > > PTRACE_MODE_ATTACH on its parent. > > > > > > > > > > About Yama, the patched keyctl_session_to_parent() function already > > > > > check if the current's and the parent's credentials are the same before > > > > > this new ptrace_may_access() check. > > > > > > > > prepare_exec_creds() in execve() always creates new credentials which > > > > are stored in bprm->cred and then later committed in begin_new_exec(). > > > > Also, fork() always copies the credentials in copy_creds(). > > > > So the "mycred == pcred" condition in keyctl_session_to_parent() > > > > basically never applies, I think. > > > > Also: When that condition is true, the whole operation is a no-op, > > > > since if the credentials are the same, then the session keyring that > > > > the credentials point to must also be the same. > > > > > > Correct, it's not a content comparison. We could compare the > > > credential's data for this specific KEYCTL_SESSION_TO_PARENT call, I > > > guess this should not be performance sensitive. > > > > Yeah, though I guess keyctl_session_to_parent() is already kind of > > doing that for the UID information; and for LSMs that would mean > > adding an extra LSM hook? > > I'm wondering why security_key_session_to_parent() was never used: see > commit 3011a344cdcd ("security: remove dead hook key_session_to_parent") While I was looking at this in another off-list thread I think I came around to the same conclusion: I think we want the security_key_session_to_parent() hook back, and while I'm wearing my SELinux hat, I think we want a SELinux implementation. Mickaël, is this something you want to work on? -- paul-moore.com ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access() 2024-07-31 20:29 ` Paul Moore @ 2024-07-31 20:53 ` Jann Horn 2024-07-31 21:27 ` Paul Moore 0 siblings, 1 reply; 14+ messages in thread From: Jann Horn @ 2024-07-31 20:53 UTC (permalink / raw) To: Paul Moore Cc: Mickaël Salaün, David Howells, Jarkko Sakkinen, Günther Noack, James Morris, Kees Cook, keyrings, linux-kernel, linux-security-module On Wed, Jul 31, 2024 at 10:29 PM Paul Moore <paul@paul-moore.com> wrote: > On Mon, Jul 29, 2024 at 11:17 AM Mickaël Salaün <mic@digikod.net> wrote: > > On Mon, Jul 29, 2024 at 05:06:10PM +0200, Jann Horn wrote: > > > On Mon, Jul 29, 2024 at 5:02 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > On Mon, Jul 29, 2024 at 04:21:01PM +0200, Jann Horn wrote: > > > > > On Mon, Jul 29, 2024 at 4:09 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > > > On Mon, Jul 29, 2024 at 03:49:29PM +0200, Jann Horn wrote: > > > > > > > On Mon, Jul 29, 2024 at 2:59 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > > > > > A process can modify its parent's credentials with > > > > > > > > KEYCTL_SESSION_TO_PARENT when their EUID and EGID are the same. This > > > > > > > > doesn't take into account all possible access controls. > > > > > > > > > > > > > > > > Enforce the same access checks as for impersonating a process. > > > > > > > > > > > > > > > > The current credentials checks are untouch because they check against > > > > > > > > EUID and EGID, whereas ptrace_may_access() checks against UID and GID. > > > > > > > > > > > > > > FWIW, my understanding is that the intended usecase of > > > > > > > KEYCTL_SESSION_TO_PARENT is that command-line tools (like "keyctl > > > > > > > new_session" and "e4crypt new_session") want to be able to change the > > > > > > > keyring of the parent process that spawned them (which I think is > > > > > > > usually a shell?); and Yama LSM, which I think is fairly widely used > > > > > > > at this point, by default prevents a child process from using > > > > > > > PTRACE_MODE_ATTACH on its parent. > > > > > > > > > > > > About Yama, the patched keyctl_session_to_parent() function already > > > > > > check if the current's and the parent's credentials are the same before > > > > > > this new ptrace_may_access() check. > > > > > > > > > > prepare_exec_creds() in execve() always creates new credentials which > > > > > are stored in bprm->cred and then later committed in begin_new_exec(). > > > > > Also, fork() always copies the credentials in copy_creds(). > > > > > So the "mycred == pcred" condition in keyctl_session_to_parent() > > > > > basically never applies, I think. > > > > > Also: When that condition is true, the whole operation is a no-op, > > > > > since if the credentials are the same, then the session keyring that > > > > > the credentials point to must also be the same. > > > > > > > > Correct, it's not a content comparison. We could compare the > > > > credential's data for this specific KEYCTL_SESSION_TO_PARENT call, I > > > > guess this should not be performance sensitive. > > > > > > Yeah, though I guess keyctl_session_to_parent() is already kind of > > > doing that for the UID information; and for LSMs that would mean > > > adding an extra LSM hook? > > > > I'm wondering why security_key_session_to_parent() was never used: see > > commit 3011a344cdcd ("security: remove dead hook key_session_to_parent") > > While I was looking at this in another off-list thread I think I came > around to the same conclusion: I think we want the > security_key_session_to_parent() hook back, and while I'm wearing my > SELinux hat, I think we want a SELinux implementation. FYI: Those checks, including the hook that formerly existed there, are (somewhat necessarily) racy wrt concurrent security context changes of the parent because they come before asynchronous work is posted to the parent to do the keyring update. In theory we could make them synchronous if we have the child wait for the parent to enter task work... actually, with that we could probably get rid of the whole cred_transfer hack and have the parent do prepare_creds() and commit_creds() normally, and propagate any errors back to the child, as long as we don't create any deadlocks with this... > Mickaël, is this something you want to work on? ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access() 2024-07-31 20:53 ` Jann Horn @ 2024-07-31 21:27 ` Paul Moore 2024-07-31 21:33 ` Jann Horn 0 siblings, 1 reply; 14+ messages in thread From: Paul Moore @ 2024-07-31 21:27 UTC (permalink / raw) To: Jann Horn Cc: Mickaël Salaün, David Howells, Jarkko Sakkinen, Günther Noack, James Morris, Kees Cook, keyrings, linux-kernel, linux-security-module On Wed, Jul 31, 2024 at 4:54 PM Jann Horn <jannh@google.com> wrote: > On Wed, Jul 31, 2024 at 10:29 PM Paul Moore <paul@paul-moore.com> wrote: > > On Mon, Jul 29, 2024 at 11:17 AM Mickaël Salaün <mic@digikod.net> wrote: > > > On Mon, Jul 29, 2024 at 05:06:10PM +0200, Jann Horn wrote: > > > > On Mon, Jul 29, 2024 at 5:02 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > > On Mon, Jul 29, 2024 at 04:21:01PM +0200, Jann Horn wrote: > > > > > > On Mon, Jul 29, 2024 at 4:09 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > > > > On Mon, Jul 29, 2024 at 03:49:29PM +0200, Jann Horn wrote: > > > > > > > > On Mon, Jul 29, 2024 at 2:59 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > > > > > > A process can modify its parent's credentials with > > > > > > > > > KEYCTL_SESSION_TO_PARENT when their EUID and EGID are the same. This > > > > > > > > > doesn't take into account all possible access controls. > > > > > > > > > > > > > > > > > > Enforce the same access checks as for impersonating a process. > > > > > > > > > > > > > > > > > > The current credentials checks are untouch because they check against > > > > > > > > > EUID and EGID, whereas ptrace_may_access() checks against UID and GID. > > > > > > > > > > > > > > > > FWIW, my understanding is that the intended usecase of > > > > > > > > KEYCTL_SESSION_TO_PARENT is that command-line tools (like "keyctl > > > > > > > > new_session" and "e4crypt new_session") want to be able to change the > > > > > > > > keyring of the parent process that spawned them (which I think is > > > > > > > > usually a shell?); and Yama LSM, which I think is fairly widely used > > > > > > > > at this point, by default prevents a child process from using > > > > > > > > PTRACE_MODE_ATTACH on its parent. > > > > > > > > > > > > > > About Yama, the patched keyctl_session_to_parent() function already > > > > > > > check if the current's and the parent's credentials are the same before > > > > > > > this new ptrace_may_access() check. > > > > > > > > > > > > prepare_exec_creds() in execve() always creates new credentials which > > > > > > are stored in bprm->cred and then later committed in begin_new_exec(). > > > > > > Also, fork() always copies the credentials in copy_creds(). > > > > > > So the "mycred == pcred" condition in keyctl_session_to_parent() > > > > > > basically never applies, I think. > > > > > > Also: When that condition is true, the whole operation is a no-op, > > > > > > since if the credentials are the same, then the session keyring that > > > > > > the credentials point to must also be the same. > > > > > > > > > > Correct, it's not a content comparison. We could compare the > > > > > credential's data for this specific KEYCTL_SESSION_TO_PARENT call, I > > > > > guess this should not be performance sensitive. > > > > > > > > Yeah, though I guess keyctl_session_to_parent() is already kind of > > > > doing that for the UID information; and for LSMs that would mean > > > > adding an extra LSM hook? > > > > > > I'm wondering why security_key_session_to_parent() was never used: see > > > commit 3011a344cdcd ("security: remove dead hook key_session_to_parent") > > > > While I was looking at this in another off-list thread I think I came > > around to the same conclusion: I think we want the > > security_key_session_to_parent() hook back, and while I'm wearing my > > SELinux hat, I think we want a SELinux implementation. > > FYI: Those checks, including the hook that formerly existed there, are > (somewhat necessarily) racy wrt concurrent security context changes of > the parent because they come before asynchronous work is posted to the > parent to do the keyring update. I was wondering about something similar while looking at keyctl_session_to_parent(), aren't all of the parent's cred checks here racy? > In theory we could make them synchronous if we have the child wait for > the parent to enter task work... actually, with that we could probably > get rid of the whole cred_transfer hack and have the parent do > prepare_creds() and commit_creds() normally, and propagate any errors > back to the child, as long as we don't create any deadlocks with > this... Assuming that no problems are caused by waiting on the parent, this might be the best approach. Should we also move, or duplicate, the cred checks into the parent's context to avoid any races? > > Mickaël, is this something you want to work on? -- paul-moore.com ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access() 2024-07-31 21:27 ` Paul Moore @ 2024-07-31 21:33 ` Jann Horn 2024-08-01 15:34 ` Mickaël Salaün 2024-08-02 13:12 ` Jann Horn 0 siblings, 2 replies; 14+ messages in thread From: Jann Horn @ 2024-07-31 21:33 UTC (permalink / raw) To: Paul Moore Cc: Mickaël Salaün, David Howells, Jarkko Sakkinen, Günther Noack, James Morris, Kees Cook, keyrings, linux-kernel, linux-security-module On Wed, Jul 31, 2024 at 11:27 PM Paul Moore <paul@paul-moore.com> wrote: > On Wed, Jul 31, 2024 at 4:54 PM Jann Horn <jannh@google.com> wrote: > > On Wed, Jul 31, 2024 at 10:29 PM Paul Moore <paul@paul-moore.com> wrote: > > > On Mon, Jul 29, 2024 at 11:17 AM Mickaël Salaün <mic@digikod.net> wrote: > > > > On Mon, Jul 29, 2024 at 05:06:10PM +0200, Jann Horn wrote: > > > > > On Mon, Jul 29, 2024 at 5:02 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > > > On Mon, Jul 29, 2024 at 04:21:01PM +0200, Jann Horn wrote: > > > > > > > On Mon, Jul 29, 2024 at 4:09 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > > > > > On Mon, Jul 29, 2024 at 03:49:29PM +0200, Jann Horn wrote: > > > > > > > > > On Mon, Jul 29, 2024 at 2:59 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > > > > > > > A process can modify its parent's credentials with > > > > > > > > > > KEYCTL_SESSION_TO_PARENT when their EUID and EGID are the same. This > > > > > > > > > > doesn't take into account all possible access controls. > > > > > > > > > > > > > > > > > > > > Enforce the same access checks as for impersonating a process. > > > > > > > > > > > > > > > > > > > > The current credentials checks are untouch because they check against > > > > > > > > > > EUID and EGID, whereas ptrace_may_access() checks against UID and GID. > > > > > > > > > > > > > > > > > > FWIW, my understanding is that the intended usecase of > > > > > > > > > KEYCTL_SESSION_TO_PARENT is that command-line tools (like "keyctl > > > > > > > > > new_session" and "e4crypt new_session") want to be able to change the > > > > > > > > > keyring of the parent process that spawned them (which I think is > > > > > > > > > usually a shell?); and Yama LSM, which I think is fairly widely used > > > > > > > > > at this point, by default prevents a child process from using > > > > > > > > > PTRACE_MODE_ATTACH on its parent. > > > > > > > > > > > > > > > > About Yama, the patched keyctl_session_to_parent() function already > > > > > > > > check if the current's and the parent's credentials are the same before > > > > > > > > this new ptrace_may_access() check. > > > > > > > > > > > > > > prepare_exec_creds() in execve() always creates new credentials which > > > > > > > are stored in bprm->cred and then later committed in begin_new_exec(). > > > > > > > Also, fork() always copies the credentials in copy_creds(). > > > > > > > So the "mycred == pcred" condition in keyctl_session_to_parent() > > > > > > > basically never applies, I think. > > > > > > > Also: When that condition is true, the whole operation is a no-op, > > > > > > > since if the credentials are the same, then the session keyring that > > > > > > > the credentials point to must also be the same. > > > > > > > > > > > > Correct, it's not a content comparison. We could compare the > > > > > > credential's data for this specific KEYCTL_SESSION_TO_PARENT call, I > > > > > > guess this should not be performance sensitive. > > > > > > > > > > Yeah, though I guess keyctl_session_to_parent() is already kind of > > > > > doing that for the UID information; and for LSMs that would mean > > > > > adding an extra LSM hook? > > > > > > > > I'm wondering why security_key_session_to_parent() was never used: see > > > > commit 3011a344cdcd ("security: remove dead hook key_session_to_parent") > > > > > > While I was looking at this in another off-list thread I think I came > > > around to the same conclusion: I think we want the > > > security_key_session_to_parent() hook back, and while I'm wearing my > > > SELinux hat, I think we want a SELinux implementation. > > > > FYI: Those checks, including the hook that formerly existed there, are > > (somewhat necessarily) racy wrt concurrent security context changes of > > the parent because they come before asynchronous work is posted to the > > parent to do the keyring update. > > I was wondering about something similar while looking at > keyctl_session_to_parent(), aren't all of the parent's cred checks > here racy? Yeah... > > In theory we could make them synchronous if we have the child wait for > > the parent to enter task work... actually, with that we could probably > > get rid of the whole cred_transfer hack and have the parent do > > prepare_creds() and commit_creds() normally, and propagate any errors > > back to the child, as long as we don't create any deadlocks with > > this... > > Assuming that no problems are caused by waiting on the parent, this > might be the best approach. Should we also move, or duplicate, the > cred checks into the parent's context to avoid any races? Yeah, I think that'd probably be a reasonable way to do it. Post task work to the parent, wait for the task work to finish (with an interruptible sleep that cancels the work item on EINTR), and then do the checks and stuff in the parent. I guess whether we should also do racy checks in the child before that depends on whether we're worried about a child without the necessary permissions being able to cause spurious syscall restarts in the parent... > > > Mickaël, is this something you want to work on? > > -- > paul-moore.com ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access() 2024-07-31 21:33 ` Jann Horn @ 2024-08-01 15:34 ` Mickaël Salaün 2024-08-02 13:12 ` Jann Horn 1 sibling, 0 replies; 14+ messages in thread From: Mickaël Salaün @ 2024-08-01 15:34 UTC (permalink / raw) To: Jann Horn, Kees Cook Cc: Paul Moore, David Howells, Jarkko Sakkinen, Günther Noack, James Morris, keyrings, linux-kernel, linux-security-module On Wed, Jul 31, 2024 at 11:33:04PM +0200, Jann Horn wrote: > On Wed, Jul 31, 2024 at 11:27 PM Paul Moore <paul@paul-moore.com> wrote: > > On Wed, Jul 31, 2024 at 4:54 PM Jann Horn <jannh@google.com> wrote: > > > On Wed, Jul 31, 2024 at 10:29 PM Paul Moore <paul@paul-moore.com> wrote: > > > > On Mon, Jul 29, 2024 at 11:17 AM Mickaël Salaün <mic@digikod.net> wrote: > > > > > On Mon, Jul 29, 2024 at 05:06:10PM +0200, Jann Horn wrote: > > > > > > On Mon, Jul 29, 2024 at 5:02 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > > > > On Mon, Jul 29, 2024 at 04:21:01PM +0200, Jann Horn wrote: > > > > > > > > On Mon, Jul 29, 2024 at 4:09 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > > > > > > On Mon, Jul 29, 2024 at 03:49:29PM +0200, Jann Horn wrote: > > > > > > > > > > On Mon, Jul 29, 2024 at 2:59 PM Mickaël Salaün <mic@digikod.net> wrote: > > > > > > > > > > > A process can modify its parent's credentials with > > > > > > > > > > > KEYCTL_SESSION_TO_PARENT when their EUID and EGID are the same. This > > > > > > > > > > > doesn't take into account all possible access controls. > > > > > > > > > > > > > > > > > > > > > > Enforce the same access checks as for impersonating a process. > > > > > > > > > > > > > > > > > > > > > > The current credentials checks are untouch because they check against > > > > > > > > > > > EUID and EGID, whereas ptrace_may_access() checks against UID and GID. > > > > > > > > > > > > > > > > > > > > FWIW, my understanding is that the intended usecase of > > > > > > > > > > KEYCTL_SESSION_TO_PARENT is that command-line tools (like "keyctl > > > > > > > > > > new_session" and "e4crypt new_session") want to be able to change the > > > > > > > > > > keyring of the parent process that spawned them (which I think is > > > > > > > > > > usually a shell?); and Yama LSM, which I think is fairly widely used > > > > > > > > > > at this point, by default prevents a child process from using > > > > > > > > > > PTRACE_MODE_ATTACH on its parent. > > > > > > > > > > > > > > > > > > About Yama, the patched keyctl_session_to_parent() function already > > > > > > > > > check if the current's and the parent's credentials are the same before > > > > > > > > > this new ptrace_may_access() check. > > > > > > > > > > > > > > > > prepare_exec_creds() in execve() always creates new credentials which > > > > > > > > are stored in bprm->cred and then later committed in begin_new_exec(). > > > > > > > > Also, fork() always copies the credentials in copy_creds(). > > > > > > > > So the "mycred == pcred" condition in keyctl_session_to_parent() > > > > > > > > basically never applies, I think. > > > > > > > > Also: When that condition is true, the whole operation is a no-op, > > > > > > > > since if the credentials are the same, then the session keyring that > > > > > > > > the credentials point to must also be the same. > > > > > > > > > > > > > > Correct, it's not a content comparison. We could compare the > > > > > > > credential's data for this specific KEYCTL_SESSION_TO_PARENT call, I > > > > > > > guess this should not be performance sensitive. > > > > > > > > > > > > Yeah, though I guess keyctl_session_to_parent() is already kind of > > > > > > doing that for the UID information; and for LSMs that would mean > > > > > > adding an extra LSM hook? > > > > > > > > > > I'm wondering why security_key_session_to_parent() was never used: see > > > > > commit 3011a344cdcd ("security: remove dead hook key_session_to_parent") > > > > > > > > While I was looking at this in another off-list thread I think I came > > > > around to the same conclusion: I think we want the > > > > security_key_session_to_parent() hook back, and while I'm wearing my > > > > SELinux hat, I think we want a SELinux implementation. > > > > > > FYI: Those checks, including the hook that formerly existed there, are > > > (somewhat necessarily) racy wrt concurrent security context changes of > > > the parent because they come before asynchronous work is posted to the > > > parent to do the keyring update. > > > > I was wondering about something similar while looking at > > keyctl_session_to_parent(), aren't all of the parent's cred checks > > here racy? > > Yeah... > > > > In theory we could make them synchronous if we have the child wait for > > > the parent to enter task work... actually, with that we could probably > > > get rid of the whole cred_transfer hack and have the parent do > > > prepare_creds() and commit_creds() normally, and propagate any errors > > > back to the child, as long as we don't create any deadlocks with > > > this... > > > > Assuming that no problems are caused by waiting on the parent, this > > might be the best approach. Should we also move, or duplicate, the > > cred checks into the parent's context to avoid any races? > > Yeah, I think that'd probably be a reasonable way to do it. Post task > work to the parent, wait for the task work to finish (with an > interruptible sleep that cancels the work item on EINTR), and then do > the checks and stuff in the parent. I guess whether we should also do > racy checks in the child before that depends on whether we're worried > about a child without the necessary permissions being able to cause > spurious syscall restarts in the parent... Why doing the check only in the parent and reporting back the result to the child could be a security issue? I guess duplicating the check would just avoid executing useless code in the parent side if the child doesn't have enough privileges right? > > > > > Mickaël, is this something you want to work on? I'll let you handle the new design of the hook, but I'll review it. :) I guess we're not OK to tie the KEYCTL_SESSION_TO_PARENT call to a ptrace_may_access() mainly because of the Yama case? I'm wondering if we should add an exception for Yama here, or if each LSM should implement its own new hook with the related new bit of security policy. I guess some systems with a fine-tuned SELinux policy could be an issue too. Anyway, I wondering what was the motivation to only/mainly check EUID/EGID for keyring change. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access() 2024-07-31 21:33 ` Jann Horn 2024-08-01 15:34 ` Mickaël Salaün @ 2024-08-02 13:12 ` Jann Horn 1 sibling, 0 replies; 14+ messages in thread From: Jann Horn @ 2024-08-02 13:12 UTC (permalink / raw) To: Paul Moore Cc: Mickaël Salaün, David Howells, Jarkko Sakkinen, Günther Noack, James Morris, Kees Cook, keyrings, linux-kernel, linux-security-module On Wed, Jul 31, 2024 at 11:33 PM Jann Horn <jannh@google.com> wrote: > On Wed, Jul 31, 2024 at 11:27 PM Paul Moore <paul@paul-moore.com> wrote: > > On Wed, Jul 31, 2024 at 4:54 PM Jann Horn <jannh@google.com> wrote: > > > FYI: Those checks, including the hook that formerly existed there, are > > > (somewhat necessarily) racy wrt concurrent security context changes of > > > the parent because they come before asynchronous work is posted to the > > > parent to do the keyring update. > > > > I was wondering about something similar while looking at > > keyctl_session_to_parent(), aren't all of the parent's cred checks > > here racy? > > Yeah... > > > > In theory we could make them synchronous if we have the child wait for > > > the parent to enter task work... actually, with that we could probably > > > get rid of the whole cred_transfer hack and have the parent do > > > prepare_creds() and commit_creds() normally, and propagate any errors > > > back to the child, as long as we don't create any deadlocks with > > > this... > > > > Assuming that no problems are caused by waiting on the parent, this > > might be the best approach. Should we also move, or duplicate, the > > cred checks into the parent's context to avoid any races? > > Yeah, I think that'd probably be a reasonable way to do it. Post task > work to the parent, wait for the task work to finish (with an > interruptible sleep that cancels the work item on EINTR), and then do > the checks and stuff in the parent. I guess whether we should also do > racy checks in the child before that depends on whether we're worried > about a child without the necessary permissions being able to cause > spurious syscall restarts in the parent... I hacked up an RFC patch for this approach: https://lore.kernel.org/r/20240802-remove-cred-transfer-v1-1-b3fef1ef2ade@google.com ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access() 2024-07-29 12:58 [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access() Mickaël Salaün 2024-07-29 13:49 ` Jann Horn @ 2024-07-29 14:06 ` Jarkko Sakkinen 1 sibling, 0 replies; 14+ messages in thread From: Jarkko Sakkinen @ 2024-07-29 14:06 UTC (permalink / raw) To: Mickaël Salaün, David Howells, Jarkko Sakkinen Cc: Günther Noack, James Morris, Jann Horn, Kees Cook, Paul Moore, keyrings, linux-kernel, linux-security-module On Mon Jul 29, 2024 at 3:58 PM EEST, Mickaël Salaün wrote: > A process can modify its parent's credentials with > KEYCTL_SESSION_TO_PARENT when their EUID and EGID are the same. This > doesn't take into account all possible access controls. Add a smoke test transcript here, which demonstrates the above for A/B testing sake so that there is no need to invent one by the reviewer. Otherwise, it is too involved to give tested-by tag to this patch. > > Enforce the same access checks as for impersonating a process. > > The current credentials checks are untouch because they check against > EUID and EGID, whereas ptrace_may_access() checks against UID and GID. > > Cc: David Howells <dhowells@redhat.com> > Cc: Günther Noack <gnoack@google.com> > Cc: James Morris <jmorris@namei.org> > Cc: Jann Horn <jannh@google.com> > Cc: Jarkko Sakkinen <jarkko@kernel.org> > Cc: Kees Cook <kees@kernel.org> > Cc: Paul Moore <paul@paul-moore.com> > Fixes: ee18d64c1f63 ("KEYS: Add a keyctl to install a process's session keyring on its parent [try #6]") > Signed-off-by: Mickaël Salaün <mic@digikod.net> > Link: https://lore.kernel.org/r/20240729125846.1043211-1-mic@digikod.net > --- > security/keys/keyctl.c | 5 +++++ > 1 file changed, 5 insertions(+) > > diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c > index ab927a142f51..511bf79fa14c 100644 > --- a/security/keys/keyctl.c > +++ b/security/keys/keyctl.c > @@ -21,6 +21,7 @@ > #include <linux/security.h> > #include <linux/uio.h> > #include <linux/uaccess.h> > +#include <linux/ptrace.h> > #include <keys/request_key_auth-type.h> > #include "internal.h" > > @@ -1687,6 +1688,10 @@ long keyctl_session_to_parent(void) > !gid_eq(pcred->sgid, mycred->egid)) > goto unlock; > > + /* The child must be allowed to impersonate its parent process. */ > + if (!ptrace_may_access(parent, PTRACE_MODE_ATTACH_REALCREDS)) > + goto unlock; > + > /* the keyrings must have the same UID */ > if ((pcred->session_keyring && > !uid_eq(pcred->session_keyring->uid, mycred->euid)) || > > base-commit: 8400291e289ee6b2bf9779ff1c83a291501f017b BR, Jarkko ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2024-08-02 13:13 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-07-29 12:58 [PATCH v1] keys: Restrict KEYCTL_SESSION_TO_PARENT according to ptrace_may_access() Mickaël Salaün 2024-07-29 13:49 ` Jann Horn 2024-07-29 14:09 ` Mickaël Salaün 2024-07-29 14:21 ` Jann Horn 2024-07-29 15:02 ` Mickaël Salaün 2024-07-29 15:06 ` Jann Horn 2024-07-29 15:17 ` Mickaël Salaün 2024-07-31 20:29 ` Paul Moore 2024-07-31 20:53 ` Jann Horn 2024-07-31 21:27 ` Paul Moore 2024-07-31 21:33 ` Jann Horn 2024-08-01 15:34 ` Mickaël Salaün 2024-08-02 13:12 ` Jann Horn 2024-07-29 14:06 ` Jarkko Sakkinen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox