summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2018-02-22 09:38:34 -0500
committerDavid Howells <dhowells@redhat.com>2018-02-22 09:38:34 -0500
commit4b34968e77ad09628cfb3c4a7daf2adc2cefc6e8 (patch)
treec10c13fc4f09f9a6705d969f6b268b060e885b3b
parent437499eea4291ae9621e8763a41df027c110a1ef (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.c21
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 */
73int restrict_link_by_signature(struct key *dest_keyring, 74int 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 */
229int restrict_link_by_key_or_keyring(struct key *dest_keyring, 234int 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 */
256int restrict_link_by_key_or_keyring_chain(struct key *dest_keyring, 261int restrict_link_by_key_or_keyring_chain(struct key *dest_keyring,
257 const struct key_type *type, 262 const struct key_type *type,