|
|
@@ -120,6 +120,18 @@ static void request_key_auth_revoke(struct key *key)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void free_request_key_auth(struct request_key_auth *rka)
|
|
|
+{
|
|
|
+ if (!rka)
|
|
|
+ return;
|
|
|
+ key_put(rka->target_key);
|
|
|
+ key_put(rka->dest_keyring);
|
|
|
+ if (rka->cred)
|
|
|
+ put_cred(rka->cred);
|
|
|
+ kfree(rka->callout_info);
|
|
|
+ kfree(rka);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Destroy an instantiation authorisation token key.
|
|
|
*/
|
|
|
@@ -129,15 +141,7 @@ static void request_key_auth_destroy(struct key *key)
|
|
|
|
|
|
kenter("{%d}", key->serial);
|
|
|
|
|
|
- if (rka->cred) {
|
|
|
- put_cred(rka->cred);
|
|
|
- rka->cred = NULL;
|
|
|
- }
|
|
|
-
|
|
|
- key_put(rka->target_key);
|
|
|
- key_put(rka->dest_keyring);
|
|
|
- kfree(rka->callout_info);
|
|
|
- kfree(rka);
|
|
|
+ free_request_key_auth(rka);
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -151,22 +155,17 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
|
|
|
const struct cred *cred = current->cred;
|
|
|
struct key *authkey = NULL;
|
|
|
char desc[20];
|
|
|
- int ret;
|
|
|
+ int ret = -ENOMEM;
|
|
|
|
|
|
kenter("%d,", target->serial);
|
|
|
|
|
|
/* allocate a auth record */
|
|
|
- rka = kmalloc(sizeof(*rka), GFP_KERNEL);
|
|
|
- if (!rka) {
|
|
|
- kleave(" = -ENOMEM");
|
|
|
- return ERR_PTR(-ENOMEM);
|
|
|
- }
|
|
|
+ rka = kzalloc(sizeof(*rka), GFP_KERNEL);
|
|
|
+ if (!rka)
|
|
|
+ goto error;
|
|
|
rka->callout_info = kmalloc(callout_len, GFP_KERNEL);
|
|
|
- if (!rka->callout_info) {
|
|
|
- kleave(" = -ENOMEM");
|
|
|
- kfree(rka);
|
|
|
- return ERR_PTR(-ENOMEM);
|
|
|
- }
|
|
|
+ if (!rka->callout_info)
|
|
|
+ goto error_free_rka;
|
|
|
|
|
|
/* see if the calling process is already servicing the key request of
|
|
|
* another process */
|
|
|
@@ -176,8 +175,12 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
|
|
|
|
|
|
/* if the auth key has been revoked, then the key we're
|
|
|
* servicing is already instantiated */
|
|
|
- if (test_bit(KEY_FLAG_REVOKED, &cred->request_key_auth->flags))
|
|
|
- goto auth_key_revoked;
|
|
|
+ if (test_bit(KEY_FLAG_REVOKED,
|
|
|
+ &cred->request_key_auth->flags)) {
|
|
|
+ up_read(&cred->request_key_auth->sem);
|
|
|
+ ret = -EKEYREVOKED;
|
|
|
+ goto error_free_rka;
|
|
|
+ }
|
|
|
|
|
|
irka = cred->request_key_auth->payload.data[0];
|
|
|
rka->cred = get_cred(irka->cred);
|
|
|
@@ -205,32 +208,23 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
|
|
|
KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL);
|
|
|
if (IS_ERR(authkey)) {
|
|
|
ret = PTR_ERR(authkey);
|
|
|
- goto error_alloc;
|
|
|
+ goto error_free_rka;
|
|
|
}
|
|
|
|
|
|
/* construct the auth key */
|
|
|
ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL);
|
|
|
if (ret < 0)
|
|
|
- goto error_inst;
|
|
|
+ goto error_put_authkey;
|
|
|
|
|
|
kleave(" = {%d,%d}", authkey->serial, refcount_read(&authkey->usage));
|
|
|
return authkey;
|
|
|
|
|
|
-auth_key_revoked:
|
|
|
- up_read(&cred->request_key_auth->sem);
|
|
|
- kfree(rka->callout_info);
|
|
|
- kfree(rka);
|
|
|
- kleave("= -EKEYREVOKED");
|
|
|
- return ERR_PTR(-EKEYREVOKED);
|
|
|
-
|
|
|
-error_inst:
|
|
|
+error_put_authkey:
|
|
|
key_revoke(authkey);
|
|
|
key_put(authkey);
|
|
|
-error_alloc:
|
|
|
- key_put(rka->target_key);
|
|
|
- key_put(rka->dest_keyring);
|
|
|
- kfree(rka->callout_info);
|
|
|
- kfree(rka);
|
|
|
+error_free_rka:
|
|
|
+ free_request_key_auth(rka);
|
|
|
+error:
|
|
|
kleave("= %d", ret);
|
|
|
return ERR_PTR(ret);
|
|
|
}
|