Linux NFS development
 help / color / mirror / Atom feed
From: Carl Hetherington <cth@carlh.net>
To: linux-nfs@vger.kernel.org
Subject: [PATCHv2 1/2] intermittent erroneous uid/gid bug with NFS4/Kerberos
Date: Mon, 6 Oct 2014 15:36:05 +0100 (BST)	[thread overview]
Message-ID: <alpine.DEB.2.02.1410061533320.27485@main.carlh.net> (raw)

KEYS: Add a new function request_valid_key_with_auxdata()
which does as request_key_with_auxdata() except that invalidated, revoked and
expired keys are ignored during the search for the requested key.

Signed-off-by: Carl Hetherington <cth@carlh.net>
---
  include/linux/key.h         |  6 +++++
  security/keys/internal.h    |  3 ++-
  security/keys/keyctl.c      |  2 +-
  security/keys/request_key.c | 59 ++++++++++++++++++++++++++++++++++++++-------
  4 files changed, 59 insertions(+), 11 deletions(-)

diff --git a/include/linux/key.h b/include/linux/key.h
index 80d6774..6a4ef03 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -252,6 +252,12 @@ extern struct key *request_key_with_auxdata(struct key_type *type,
  					    size_t callout_len,
  					    void *aux);

+extern struct key *request_valid_key_with_auxdata(struct key_type *type,
+						  const char *description,
+						  const void *callout_info,
+						  size_t callout_len,
+						  void *aux);
+
  extern struct key *request_key_async(struct key_type *type,
  				     const char *description,
  				     const void *callout_info,
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 80b2aac..5c9bc62 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -150,7 +150,8 @@ extern struct key *request_key_and_link(struct key_type *type,
  					size_t callout_len,
  					void *aux,
  					struct key *dest_keyring,
-					unsigned long flags);
+					unsigned long key_alloc_flags,
+					unsigned long keyring_search_flags);

  extern int lookup_user_key_possessed(const struct key *key, const void *target);
  extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index cee72ce..25a12bc 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -212,7 +212,7 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type,
  	/* do the search */
  	key = request_key_and_link(ktype, description, callout_info,
  				   callout_len, NULL, key_ref_to_ptr(dest_ref),
-				   KEY_ALLOC_IN_QUOTA);
+				   KEY_ALLOC_IN_QUOTA, 0);
  	if (IS_ERR(key)) {
  		ret = PTR_ERR(key);
  		goto error5;
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 3814119..9f78aed 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -500,7 +500,11 @@ couldnt_alloc_key:
   * @callout_len: The length of callout_info.
   * @aux: Auxiliary data for the upcall.
   * @dest_keyring: Where to cache the key.
- * @flags: Flags to key_alloc().
+ * @key_alloc_flags: Flags to key_alloc().
+ * @keyring_search_flags: Flags to pass in the keyring search context
+ * (in addition to KEYRING_SEARCH_LOOKUP_DIRECT).  For example, passing
+ * KEYRING_SEARCH_DO_STATE_CHECK here will stop the function returning
+ * invalidated, revoked or expired keys.
   *
   * A key matching the specified criteria is searched for in the process's
   * keyrings and returned with its usage count incremented if found.  Otherwise,
@@ -525,7 +529,8 @@ struct key *request_key_and_link(struct key_type *type,
  				 size_t callout_len,
  				 void *aux,
  				 struct key *dest_keyring,
-				 unsigned long flags)
+				 unsigned long key_alloc_flags,
+				 unsigned long keyring_search_flags)
  {
  	struct keyring_search_context ctx = {
  		.index_key.type		= type,
@@ -533,7 +538,7 @@ struct key *request_key_and_link(struct key_type *type,
  		.cred			= current_cred(),
  		.match			= type->match,
  		.match_data		= description,
-		.flags			= KEYRING_SEARCH_LOOKUP_DIRECT,
+		.flags			= KEYRING_SEARCH_LOOKUP_DIRECT | keyring_search_flags,
  	};
  	struct key *key;
  	key_ref_t key_ref;
@@ -541,7 +546,7 @@ struct key *request_key_and_link(struct key_type *type,

  	kenter("%s,%s,%p,%zu,%p,%p,%lx",
  	       ctx.index_key.type->name, ctx.index_key.description,
-	       callout_info, callout_len, aux, dest_keyring, flags);
+	       callout_info, callout_len, aux, dest_keyring, key_alloc_flags);

  	/* search all the process keyrings for a key */
  	key_ref = search_process_keyrings(&ctx);
@@ -568,7 +573,7 @@ struct key *request_key_and_link(struct key_type *type,
  			goto error;

  		key = construct_key_and_link(&ctx, callout_info, callout_len,
-					     aux, dest_keyring, flags);
+					     aux, dest_keyring, key_alloc_flags);
  	}

  error:
@@ -629,7 +634,7 @@ struct key *request_key(struct key_type *type,
  	if (callout_info)
  		callout_len = strlen(callout_info);
  	key = request_key_and_link(type, description, callout_info, callout_len,
-				   NULL, NULL, KEY_ALLOC_IN_QUOTA);
+				   NULL, NULL, KEY_ALLOC_IN_QUOTA, 0);
  	if (!IS_ERR(key)) {
  		ret = wait_for_key_construction(key, false);
  		if (ret < 0) {
@@ -665,7 +670,7 @@ struct key *request_key_with_auxdata(struct key_type *type,
  	int ret;

  	key = request_key_and_link(type, description, callout_info, callout_len,
-				   aux, NULL, KEY_ALLOC_IN_QUOTA);
+				   aux, NULL, KEY_ALLOC_IN_QUOTA, 0);
  	if (!IS_ERR(key)) {
  		ret = wait_for_key_construction(key, false);
  		if (ret < 0) {
@@ -677,6 +682,42 @@ struct key *request_key_with_auxdata(struct key_type *type,
  }
  EXPORT_SYMBOL(request_key_with_auxdata);

+/**
+ * request_valid_key_with_auxdata - Request a key with auxiliary data for the upcaller
+ * @type: The type of key we want.
+ * @description: The searchable description of the key.
+ * @callout_info: The data to pass to the instantiation upcall (or NULL).
+ * @callout_len: The length of callout_info.
+ * @aux: Auxiliary data for the upcall.
+ *
+ * As for request_key_with_auxdata() except that existing invalidated, revoked and expired
+ * keys are ignored during the search for the requested key.
+ *
+ * Furthermore, it then works as wait_for_key_construction() to wait for the
+ * completion of keys undergoing construction with a non-interruptible wait.
+ */
+struct key *request_valid_key_with_auxdata(struct key_type *type,
+				     const char *description,
+				     const void *callout_info,
+				     size_t callout_len,
+				     void *aux)
+{
+	struct key *key;
+	int ret;
+
+	key = request_key_and_link(type, description, callout_info, callout_len,
+				   aux, NULL, KEY_ALLOC_IN_QUOTA, KEYRING_SEARCH_DO_STATE_CHECK);
+	if (!IS_ERR(key)) {
+		ret = wait_for_key_construction(key, false);
+		if (ret < 0) {
+			key_put(key);
+			return ERR_PTR(ret);
+		}
+	}
+	return key;
+}
+EXPORT_SYMBOL(request_valid_key_with_auxdata);
+
  /*
   * request_key_async - Request a key (allow async construction)
   * @type: Type of key.
@@ -698,7 +739,7 @@ struct key *request_key_async(struct key_type *type,
  {
  	return request_key_and_link(type, description, callout_info,
  				    callout_len, NULL, NULL,
-				    KEY_ALLOC_IN_QUOTA);
+				    KEY_ALLOC_IN_QUOTA, 0);
  }
  EXPORT_SYMBOL(request_key_async);

@@ -723,6 +764,6 @@ struct key *request_key_async_with_auxdata(struct key_type *type,
  					   void *aux)
  {
  	return request_key_and_link(type, description, callout_info,
-				    callout_len, aux, NULL, KEY_ALLOC_IN_QUOTA);
+				    callout_len, aux, NULL, KEY_ALLOC_IN_QUOTA, 0);
  }
  EXPORT_SYMBOL(request_key_async_with_auxdata);
-- 
1.9.1




             reply	other threads:[~2014-10-06 14:36 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-06 14:36 Carl Hetherington [this message]
2014-10-06 20:08 ` [PATCHv2 1/2] intermittent erroneous uid/gid bug with NFS4/Kerberos Anna Schumaker
2014-10-07 15:20   ` Carl Hetherington

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=alpine.DEB.2.02.1410061533320.27485@main.carlh.net \
    --to=cth@carlh.net \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox