struct request_key_auth *rka;
        key_ref_t key_ref, ret, err;
 
+       might_sleep();
+
        /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
         * searchable, but we failed to find a key or we found a negative key;
         * otherwise we want to return a sample error (probably -EACCES) if
         */
        if (context->request_key_auth &&
            context == current &&
-           type != &key_type_request_key_auth &&
-           key_validate(context->request_key_auth) == 0
+           type != &key_type_request_key_auth
            ) {
-               rka = context->request_key_auth->payload.data;
+               /* defend against the auth key being revoked */
+               down_read(&context->request_key_auth->sem);
 
-               key_ref = search_process_keyrings(type, description, match,
-                                                 rka->context);
+               if (key_validate(context->request_key_auth) == 0) {
+                       rka = context->request_key_auth->payload.data;
 
-               if (!IS_ERR(key_ref))
-                       goto found;
+                       key_ref = search_process_keyrings(type, description,
+                                                         match, rka->context);
 
-               switch (PTR_ERR(key_ref)) {
-               case -EAGAIN: /* no key */
-                       if (ret)
+                       up_read(&context->request_key_auth->sem);
+
+                       if (!IS_ERR(key_ref))
+                               goto found;
+
+                       switch (PTR_ERR(key_ref)) {
+                       case -EAGAIN: /* no key */
+                               if (ret)
+                                       break;
+                       case -ENOKEY: /* negative key */
+                               ret = key_ref;
                                break;
-               case -ENOKEY: /* negative key */
-                       ret = key_ref;
-                       break;
-               default:
-                       err = key_ref;
-                       break;
+                       default:
+                               err = key_ref;
+                               break;
+                       }
+               } else {
+                       up_read(&context->request_key_auth->sem);
                }
        }
 
 
 
 static int request_key_auth_instantiate(struct key *, const void *, size_t);
 static void request_key_auth_describe(const struct key *, struct seq_file *);
+static void request_key_auth_revoke(struct key *);
 static void request_key_auth_destroy(struct key *);
 static long request_key_auth_read(const struct key *, char __user *, size_t);
 
        .def_datalen    = sizeof(struct request_key_auth),
        .instantiate    = request_key_auth_instantiate,
        .describe       = request_key_auth_describe,
+       .revoke         = request_key_auth_revoke,
        .destroy        = request_key_auth_destroy,
        .read           = request_key_auth_read,
 };
 
 } /* end request_key_auth_read() */
 
+/*****************************************************************************/
+/*
+ * handle revocation of an authorisation token key
+ * - called with the key sem write-locked
+ */
+static void request_key_auth_revoke(struct key *key)
+{
+       struct request_key_auth *rka = key->payload.data;
+
+       kenter("{%d}", key->serial);
+
+       if (rka->context) {
+               put_task_struct(rka->context);
+               rka->context = NULL;
+       }
+
+} /* end request_key_auth_revoke() */
+
 /*****************************************************************************/
 /*
  * destroy an instantiation authorisation token key
 
        kenter("{%d}", key->serial);
 
+       if (rka->context) {
+               put_task_struct(rka->context);
+               rka->context = NULL;
+       }
+
        key_put(rka->target_key);
        kfree(rka);
 
         * another process */
        if (current->request_key_auth) {
                /* it is - use that instantiation context here too */
+               down_read(¤t->request_key_auth->sem);
+
+               /* if the auth key has been revoked, then the key we're
+                * servicing is already instantiated */
+               if (test_bit(KEY_FLAG_REVOKED,
+                            ¤t->request_key_auth->flags))
+                       goto auth_key_revoked;
+
                irka = current->request_key_auth->payload.data;
                rka->context = irka->context;
                rka->pid = irka->pid;
+               get_task_struct(rka->context);
+
+               up_read(¤t->request_key_auth->sem);
        }
        else {
                /* it isn't - use this process as the context */
                rka->context = current;
                rka->pid = current->pid;
+               get_task_struct(rka->context);
        }
 
        rka->target_key = key_get(target);
        if (ret < 0)
                goto error_inst;
 
-       kleave(" = {%d})", authkey->serial);
+       kleave(" = {%d}", authkey->serial);
        return authkey;
 
+auth_key_revoked:
+       up_read(¤t->request_key_auth->sem);
+       kfree(rka);
+       kleave("= -EKEYREVOKED");
+       return ERR_PTR(-EKEYREVOKED);
+
 error_inst:
        key_revoke(authkey);
        key_put(authkey);