All of lore.kernel.org
 help / color / mirror / Atom feed
From: Scott Mayhew <smayhew@redhat.com>
To: linux-nfs@vger.kernel.org, keyrings@vger.kernel.org
Subject: [RFC PATCH 4/5] keys: add the ability to search user keyrings in search_cred_keyrings_rcu()
Date: Thu, 20 Apr 2023 16:20:03 -0400	[thread overview]
Message-ID: <20230420202004.239116-5-smayhew@redhat.com> (raw)
In-Reply-To: <20230420202004.239116-1-smayhew@redhat.com>

We want to store GSS creds in user keyrings.  Make
search_cred_keyrings_rcu() search the user keyring if it exists so that
keys containing GSS creds will be found.

Signed-off-by: Scott Mayhew <smayhew@redhat.com>
---
 security/keys/internal.h     |  1 +
 security/keys/process_keys.c | 78 ++++++++++++++++++++++++++++++------
 2 files changed, 67 insertions(+), 12 deletions(-)

diff --git a/security/keys/internal.h b/security/keys/internal.h
index 3c1e7122076b..524178802406 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -149,6 +149,7 @@ extern key_ref_t search_process_keyrings_rcu(struct keyring_search_context *ctx)
 extern struct key *find_keyring_by_name(const char *name, bool uid_keyring);
 
 extern int look_up_user_keyrings(struct key **, struct key **);
+extern struct key *get_user_keyring_rcu(const struct cred *);
 extern struct key *get_user_session_keyring_rcu(const struct cred *);
 extern int install_thread_keyring_to_cred(struct cred *);
 extern int install_process_keyring_to_cred(struct cred *);
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index b5d5333ab330..c78b13a0c5a2 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -179,13 +179,12 @@ int look_up_user_keyrings(struct key **_user_keyring,
 }
 
 /*
- * Get the user session keyring if it exists, but don't create it if it
- * doesn't.
+ * Get a keyring if it exists, but don't create it if it doesn't.
  */
-struct key *get_user_session_keyring_rcu(const struct cred *cred)
+static struct key *get_keyring_rcu(const struct cred *cred, key_serial_t id)
 {
 	struct key *reg_keyring = READ_ONCE(cred->user_ns->user_keyring_register);
-	key_ref_t session_keyring_r;
+	key_ref_t keyring_r;
 	char buf[20];
 
 	struct keyring_search_context ctx = {
@@ -201,15 +200,47 @@ struct key *get_user_session_keyring_rcu(const struct cred *cred)
 	if (!reg_keyring)
 		return NULL;
 
-	ctx.index_key.desc_len = snprintf(buf, sizeof(buf), "_uid_ses.%u",
-					  from_kuid(cred->user_ns,
-						    cred->user->uid));
+	switch (id) {
+	case KEY_SPEC_USER_KEYRING:
+		ctx.index_key.desc_len = snprintf(buf, sizeof(buf),
+						  "_uid.%u",
+						  from_kuid(cred->user_ns,
+							    cred->user->uid));
+		break;
+	case KEY_SPEC_USER_SESSION_KEYRING:
+		ctx.index_key.desc_len = snprintf(buf, sizeof(buf),
+						  "_uid_ses.%u",
+						  from_kuid(cred->user_ns,
+							    cred->user->uid));
+		break;
+	default:
+		return NULL;
+		break;
+	}
 
-	session_keyring_r = keyring_search_rcu(make_key_ref(reg_keyring, true),
-					       &ctx);
-	if (IS_ERR(session_keyring_r))
+	keyring_r = keyring_search_rcu(make_key_ref(reg_keyring, true), &ctx);
+
+	if (IS_ERR(keyring_r))
 		return NULL;
-	return key_ref_to_ptr(session_keyring_r);
+	return key_ref_to_ptr(keyring_r);
+}
+
+/*
+ * Get the user keyring if it exists, but don't create it if it
+ * doesn't.
+ */
+struct key *get_user_keyring_rcu(const struct cred *cred)
+{
+	return get_keyring_rcu(cred, KEY_SPEC_USER_KEYRING);
+}
+
+/*
+ * Get the user session keyring if it exists, but don't create it if it
+ * doesn't.
+ */
+struct key *get_user_session_keyring_rcu(const struct cred *cred)
+{
+	return get_keyring_rcu(cred, KEY_SPEC_USER_SESSION_KEYRING);
 }
 
 /*
@@ -421,7 +452,7 @@ void key_fsgid_changed(struct cred *new_cred)
  */
 key_ref_t search_cred_keyrings_rcu(struct keyring_search_context *ctx)
 {
-	struct key *user_session;
+	struct key *user_session, *user;
 	key_ref_t key_ref, ret, err;
 	const struct cred *cred = ctx->cred;
 
@@ -519,6 +550,29 @@ key_ref_t search_cred_keyrings_rcu(struct keyring_search_context *ctx)
 		}
 	}
 
+	/* search the user keyring */
+	if ((user = get_user_keyring_rcu(cred))) {
+		key_ref = keyring_search_rcu(make_key_ref(user, 1),
+					     ctx);
+		key_put(user);
+
+		if (!IS_ERR(key_ref))
+			goto found;
+
+		switch (PTR_ERR(key_ref)) {
+		case -EAGAIN: /* no key */
+			if (ret)
+				break;
+			fallthrough;
+		case -ENOKEY: /* negative key */
+			ret = key_ref;
+			break;
+		default:
+			err = key_ref;
+			break;
+		}
+	}
+
 	/* no key - decide on the error we're going to go for */
 	key_ref = ret ? ret : err;
 
-- 
2.39.2


  parent reply	other threads:[~2023-04-20 20:21 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-20 20:19 [RFC PATCH 0/5] SUNRPC: Add option to store GSS credentials in Scott Mayhew
2023-04-20 20:20 ` [RFC PATCH 1/5] keys: export keyring_ptr_to_key() Scott Mayhew
2023-04-20 20:20 ` [RFC PATCH 2/5] keys: add keyring_gc_custom() Scott Mayhew
2023-04-20 20:20 ` [RFC PATCH 3/5] keys: add dest_keyring parameter to request_key_with_auxdata() Scott Mayhew
2023-04-20 20:20 ` Scott Mayhew [this message]
2023-04-20 20:20 ` [RFC PATCH 5/5] SUNRPC: store GSS creds in keyrings Scott Mayhew
2023-04-20 21:54   ` kernel test robot
2023-04-21  3:32   ` kernel test robot
2023-04-21  5:14   ` kernel test robot
2023-04-21  6:15   ` kernel test robot
2023-04-21 10:13   ` Dan Carpenter
2023-04-22 21:27   ` Ben Boeckel
2023-04-24 14:02     ` Scott Mayhew
2023-04-24 14:23       ` Ben Boeckel
2023-04-24 15:01         ` Scott Mayhew
2023-04-24 18:28           ` Ben Boeckel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230420202004.239116-5-smayhew@redhat.com \
    --to=smayhew@redhat.com \
    --cc=keyrings@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.