diff options
author | Eric Biggers <ebiggers@google.com> | 2018-02-22 09:38:34 -0500 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2018-02-22 09:38:34 -0500 |
commit | 4b34968e77ad09628cfb3c4a7daf2adc2cefc6e8 (patch) | |
tree | c10c13fc4f09f9a6705d969f6b268b060e885b3b | |
parent | 437499eea4291ae9621e8763a41df027c110a1ef (diff) |
X.509: fix NULL dereference when restricting key with unsupported_sig
The asymmetric key type allows an X.509 certificate to be added even if
its signature's hash algorithm is not available in the crypto API. In
that case 'payload.data[asym_auth]' will be NULL. But the key
restriction code failed to check for this case before trying to use the
signature, resulting in a NULL pointer dereference in
key_or_keyring_common() or in restrict_link_by_signature().
Fix this by returning -ENOPKG when the signature is unsupported.
Reproducer when all the CONFIG_CRYPTO_SHA512* options are disabled and
keyctl has support for the 'restrict_keyring' command:
keyctl new_session
keyctl restrict_keyring @s asymmetric builtin_trusted
openssl req -new -sha512 -x509 -batch -nodes -outform der \
| keyctl padd asymmetric desc @s
Fixes: a511e1af8b12 ("KEYS: Move the point of trust determination to __key_link()")
Cc: <stable@vger.kernel.org> # v4.7+
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r-- | crypto/asymmetric_keys/restrict.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c index 86fb68508952..7c93c7728454 100644 --- a/crypto/asymmetric_keys/restrict.c +++ b/crypto/asymmetric_keys/restrict.c | |||
@@ -67,8 +67,9 @@ __setup("ca_keys=", ca_keys_setup); | |||
67 | * | 67 | * |
68 | * Returns 0 if the new certificate was accepted, -ENOKEY if we couldn't find a | 68 | * Returns 0 if the new certificate was accepted, -ENOKEY if we couldn't find a |
69 | * matching parent certificate in the trusted list, -EKEYREJECTED if the | 69 | * matching parent certificate in the trusted list, -EKEYREJECTED if the |
70 | * signature check fails or the key is blacklisted and some other error if | 70 | * signature check fails or the key is blacklisted, -ENOPKG if the signature |
71 | * there is a matching certificate but the signature check cannot be performed. | 71 | * uses unsupported crypto, or some other error if there is a matching |
72 | * certificate but the signature check cannot be performed. | ||
72 | */ | 73 | */ |
73 | int restrict_link_by_signature(struct key *dest_keyring, | 74 | int restrict_link_by_signature(struct key *dest_keyring, |
74 | const struct key_type *type, | 75 | const struct key_type *type, |
@@ -88,6 +89,8 @@ int restrict_link_by_signature(struct key *dest_keyring, | |||
88 | return -EOPNOTSUPP; | 89 | return -EOPNOTSUPP; |
89 | 90 | ||
90 | sig = payload->data[asym_auth]; | 91 | sig = payload->data[asym_auth]; |
92 | if (!sig) | ||
93 | return -ENOPKG; | ||
91 | if (!sig->auth_ids[0] && !sig->auth_ids[1]) | 94 | if (!sig->auth_ids[0] && !sig->auth_ids[1]) |
92 | return -ENOKEY; | 95 | return -ENOKEY; |
93 | 96 | ||
@@ -139,6 +142,8 @@ static int key_or_keyring_common(struct key *dest_keyring, | |||
139 | return -EOPNOTSUPP; | 142 | return -EOPNOTSUPP; |
140 | 143 | ||
141 | sig = payload->data[asym_auth]; | 144 | sig = payload->data[asym_auth]; |
145 | if (!sig) | ||
146 | return -ENOPKG; | ||
142 | if (!sig->auth_ids[0] && !sig->auth_ids[1]) | 147 | if (!sig->auth_ids[0] && !sig->auth_ids[1]) |
143 | return -ENOKEY; | 148 | return -ENOKEY; |
144 | 149 | ||
@@ -222,9 +227,9 @@ static int key_or_keyring_common(struct key *dest_keyring, | |||
222 | * | 227 | * |
223 | * Returns 0 if the new certificate was accepted, -ENOKEY if we | 228 | * Returns 0 if the new certificate was accepted, -ENOKEY if we |
224 | * couldn't find a matching parent certificate in the trusted list, | 229 | * couldn't find a matching parent certificate in the trusted list, |
225 | * -EKEYREJECTED if the signature check fails, and some other error if | 230 | * -EKEYREJECTED if the signature check fails, -ENOPKG if the signature uses |
226 | * there is a matching certificate but the signature check cannot be | 231 | * unsupported crypto, or some other error if there is a matching certificate |
227 | * performed. | 232 | * but the signature check cannot be performed. |
228 | */ | 233 | */ |
229 | int restrict_link_by_key_or_keyring(struct key *dest_keyring, | 234 | int restrict_link_by_key_or_keyring(struct key *dest_keyring, |
230 | const struct key_type *type, | 235 | const struct key_type *type, |
@@ -249,9 +254,9 @@ int restrict_link_by_key_or_keyring(struct key *dest_keyring, | |||
249 | * | 254 | * |
250 | * Returns 0 if the new certificate was accepted, -ENOKEY if we | 255 | * Returns 0 if the new certificate was accepted, -ENOKEY if we |
251 | * couldn't find a matching parent certificate in the trusted list, | 256 | * couldn't find a matching parent certificate in the trusted list, |
252 | * -EKEYREJECTED if the signature check fails, and some other error if | 257 | * -EKEYREJECTED if the signature check fails, -ENOPKG if the signature uses |
253 | * there is a matching certificate but the signature check cannot be | 258 | * unsupported crypto, or some other error if there is a matching certificate |
254 | * performed. | 259 | * but the signature check cannot be performed. |
255 | */ | 260 | */ |
256 | int restrict_link_by_key_or_keyring_chain(struct key *dest_keyring, | 261 | int restrict_link_by_key_or_keyring_chain(struct key *dest_keyring, |
257 | const struct key_type *type, | 262 | const struct key_type *type, |