Skip to content

Commit 72f9a07

Browse files
ebiggersdhowells
authored andcommitted
KEYS: be careful with error codes in public_key_verify_signature()
In public_key_verify_signature(), if akcipher_request_alloc() fails, we return -ENOMEM. But that error code was set 25 lines above, and by accident someone could easily insert new code in between that assigns to 'ret', which would introduce a signature verification bypass. Make the code clearer by moving the -ENOMEM down to where it is used. Additionally, the callers of public_key_verify_signature() only consider a negative return value to be an error. This means that if any positive return value is accidentally introduced deeper in the call stack (e.g. 'return EBADMSG' instead of 'return -EBADMSG' somewhere in RSA), signature verification will be bypassed. Make things more robust by having public_key_verify_signature() warn about positive errors and translate them into -EINVAL. Signed-off-by: Eric Biggers <[email protected]> Signed-off-by: David Howells <[email protected]>
1 parent a80745a commit 72f9a07

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

crypto/asymmetric_keys/public_key.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ int public_key_verify_signature(const struct public_key *pkey,
7373
char alg_name_buf[CRYPTO_MAX_ALG_NAME];
7474
void *output;
7575
unsigned int outlen;
76-
int ret = -ENOMEM;
76+
int ret;
7777

7878
pr_devel("==>%s()\n", __func__);
7979

@@ -99,6 +99,7 @@ int public_key_verify_signature(const struct public_key *pkey,
9999
if (IS_ERR(tfm))
100100
return PTR_ERR(tfm);
101101

102+
ret = -ENOMEM;
102103
req = akcipher_request_alloc(tfm, GFP_KERNEL);
103104
if (!req)
104105
goto error_free_tfm;
@@ -127,7 +128,7 @@ int public_key_verify_signature(const struct public_key *pkey,
127128
* signature and returns that to us.
128129
*/
129130
ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait);
130-
if (ret < 0)
131+
if (ret)
131132
goto out_free_output;
132133

133134
/* Do the actual verification step. */
@@ -142,6 +143,8 @@ int public_key_verify_signature(const struct public_key *pkey,
142143
error_free_tfm:
143144
crypto_free_akcipher(tfm);
144145
pr_devel("<==%s() = %d\n", __func__, ret);
146+
if (WARN_ON_ONCE(ret > 0))
147+
ret = -EINVAL;
145148
return ret;
146149
}
147150
EXPORT_SYMBOL_GPL(public_key_verify_signature);

0 commit comments

Comments
 (0)