Merge commit 'v3.17' into next
[firefly-linux-kernel-4.4.55.git] / security / keys / request_key.c
index 381411941cc1abbc48a699b1c2c38042f1a05711..bb4337c7ae1b3978fd5e36d692d8cacf27b89816 100644 (file)
 
 #define key_negative_timeout   60      /* default timeout on a negative key's existence */
 
-/*
- * wait_on_bit() sleep function for uninterruptible waiting
- */
-static int key_wait_bit(void *flags)
-{
-       schedule();
-       return 0;
-}
-
-/*
- * wait_on_bit() sleep function for interruptible waiting
- */
-static int key_wait_bit_intr(void *flags)
-{
-       schedule();
-       return signal_pending(current) ? -ERESTARTSYS : 0;
-}
-
 /**
  * complete_request_key - Complete the construction of a key.
  * @cons: The key construction record.
@@ -531,9 +513,9 @@ struct key *request_key_and_link(struct key_type *type,
                .index_key.type         = type,
                .index_key.description  = description,
                .cred                   = current_cred(),
-               .match                  = type->match,
-               .match_data             = description,
-               .flags                  = KEYRING_SEARCH_LOOKUP_DIRECT,
+               .match_data.cmp         = key_default_cmp,
+               .match_data.raw_data    = description,
+               .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
        };
        struct key *key;
        key_ref_t key_ref;
@@ -543,6 +525,14 @@ struct key *request_key_and_link(struct key_type *type,
               ctx.index_key.type->name, ctx.index_key.description,
               callout_info, callout_len, aux, dest_keyring, flags);
 
+       if (type->match_preparse) {
+               ret = type->match_preparse(&ctx.match_data);
+               if (ret < 0) {
+                       key = ERR_PTR(ret);
+                       goto error;
+               }
+       }
+
        /* search all the process keyrings for a key */
        key_ref = search_process_keyrings(&ctx);
 
@@ -555,7 +545,7 @@ struct key *request_key_and_link(struct key_type *type,
                        if (ret < 0) {
                                key_put(key);
                                key = ERR_PTR(ret);
-                               goto error;
+                               goto error_free;
                        }
                }
        } else if (PTR_ERR(key_ref) != -EAGAIN) {
@@ -565,12 +555,15 @@ struct key *request_key_and_link(struct key_type *type,
                 * should consult userspace if we can */
                key = ERR_PTR(-ENOKEY);
                if (!callout_info)
-                       goto error;
+                       goto error_free;
 
                key = construct_key_and_link(&ctx, callout_info, callout_len,
                                             aux, dest_keyring, flags);
        }
 
+error_free:
+       if (type->match_free)
+               type->match_free(&ctx.match_data);
 error:
        kleave(" = %p", key);
        return key;
@@ -592,10 +585,9 @@ int wait_for_key_construction(struct key *key, bool intr)
        int ret;
 
        ret = wait_on_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT,
-                         intr ? key_wait_bit_intr : key_wait_bit,
                          intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
-       if (ret < 0)
-               return ret;
+       if (ret)
+               return -ERESTARTSYS;
        if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
                smp_rmb();
                return key->type_data.reject_error;