diff options
Diffstat (limited to 'security/keys/request_key_auth.c')
| -rw-r--r-- | security/keys/request_key_auth.c | 76 | 
1 files changed, 34 insertions, 42 deletions
| diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index afe9d22ab361..424e1d90412e 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c @@ -73,7 +73,7 @@ static void request_key_auth_describe(const struct key *key,  	seq_puts(m, "key:");  	seq_puts(m, key->description); -	if (key_is_instantiated(key)) +	if (key_is_positive(key))  		seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);  } @@ -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,18 @@ 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->callout_info = kmalloc(callout_len, GFP_KERNEL); -	if (!rka->callout_info) { -		kleave(" = -ENOMEM"); -		kfree(rka); -		return ERR_PTR(-ENOMEM); -	} +	rka = kzalloc(sizeof(*rka), GFP_KERNEL); +	if (!rka) +		goto error; +	rka->callout_info = kmemdup(callout_info, callout_len, GFP_KERNEL); +	if (!rka->callout_info) +		goto error_free_rka; +	rka->callout_len = callout_len;  	/* see if the calling process is already servicing the key request of  	 * another process */ @@ -176,8 +176,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); @@ -193,8 +197,6 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,  	rka->target_key = key_get(target);  	rka->dest_keyring = key_get(dest_keyring); -	memcpy(rka->callout_info, callout_info, callout_len); -	rka->callout_len = callout_len;  	/* allocate the auth key */  	sprintf(desc, "%x", target->serial); @@ -205,32 +207,22 @@ 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: -	key_revoke(authkey); +error_put_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);  } |