Avoid double-free in the openssl-1.1.0 patch

This commit is contained in:
Jakub Jelen 2017-06-15 13:41:24 +02:00
parent eb751fd1d3
commit f07a0866e1

View File

@ -18,8 +18,8 @@ diff -up openssh-7.4p1/authfd.c.openssl openssh-7.4p1/authfd.c
+ (r = sshbuf_get_u32(ids, &bits)) != 0 || + (r = sshbuf_get_u32(ids, &bits)) != 0 ||
+ (r = sshbuf_get_bignum1(ids, e)) != 0 || + (r = sshbuf_get_bignum1(ids, e)) != 0 ||
+ (r = sshbuf_get_bignum1(ids, n)) != 0 || + (r = sshbuf_get_bignum1(ids, n)) != 0 ||
+ (RSA_set0_key(key->rsa, n, e, NULL) == 0) || + (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0 ||
+ (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0) { + (RSA_set0_key(key->rsa, n, e, NULL) == 0)) {
+ BN_free(n); + BN_free(n);
+ BN_free(e); + BN_free(e);
goto out; goto out;
@ -2014,7 +2014,7 @@ diff -up openssh-7.4p1/ssh-agent.c.openssl openssh-7.4p1/ssh-agent.c
if (bits != sshkey_size(key)) if (bits != sshkey_size(key))
logit("Warning: identity keysize mismatch: " logit("Warning: identity keysize mismatch: "
@@ -565,23 +577,38 @@ agent_decode_rsa1(struct sshbuf *m, stru @@ -565,23 +577,46 @@ agent_decode_rsa1(struct sshbuf *m, stru
{ {
struct sshkey *k = NULL; struct sshkey *k = NULL;
int r = SSH_ERR_INTERNAL_ERROR; int r = SSH_ERR_INTERNAL_ERROR;
@ -2043,16 +2043,24 @@ diff -up openssh-7.4p1/ssh-agent.c.openssl openssh-7.4p1/ssh-agent.c
- (r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) /* q */ - (r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) /* q */
+ (r = sshbuf_get_bignum1(m, q)) != 0 || /* p */ + (r = sshbuf_get_bignum1(m, q)) != 0 || /* p */
+ (r = sshbuf_get_bignum1(m, p)) != 0 || /* q */ + (r = sshbuf_get_bignum1(m, p)) != 0 || /* q */
+ RSA_set0_key(k->rsa, n, e, d) == 0 || + RSA_set0_key(k->rsa, n, e, d) == 0) {
+ RSA_set0_factors(k->rsa, p, q) == 0 ||
+ RSA_set0_crt_params(k->rsa, NULL, NULL, iqmp) == 0) {
+ BN_free(n); + BN_free(n);
+ BN_free(e); + BN_free(e);
+ BN_free(d); + BN_free(d);
+ BN_free(p); + BN_free(p);
+ BN_free(q); + BN_free(q);
+ BN_free(iqmp);
+ goto out;
+ }
+ if (RSA_set0_factors(k->rsa, p, q) == 0) {
+ BN_free(p);
+ BN_free(q);
+ BN_free(iqmp); + BN_free(iqmp);
goto out; goto out;
+ }
+ if (RSA_set0_crt_params(k->rsa, NULL, NULL, iqmp) == 0) {
+ BN_free(iqmp);
+ goto out;
+ } + }
/* Generate additional parameters */ /* Generate additional parameters */
@ -3099,7 +3107,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c
break; break;
# ifdef OPENSSL_HAS_ECC # ifdef OPENSSL_HAS_ECC
case KEY_ECDSA: case KEY_ECDSA:
@@ -2819,24 +2995,71 @@ sshkey_private_deserialize(struct sshbuf @@ -2819,24 +2995,84 @@ sshkey_private_deserialize(struct sshbuf
r = SSH_ERR_ALLOC_FAIL; r = SSH_ERR_ALLOC_FAIL;
goto out; goto out;
} }
@ -3179,11 +3187,24 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c
+ (r = sshbuf_get_bignum2(buf, p)) != 0 || + (r = sshbuf_get_bignum2(buf, p)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, q)) != 0 || + (r = sshbuf_get_bignum2(buf, q)) != 0 ||
+ (r = ((RSA_set0_key(k->rsa, NULL, NULL, d) == 0) + (r = ((RSA_set0_key(k->rsa, NULL, NULL, d) == 0)
+ ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0 || + ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0) {
+ (r = ((RSA_set0_factors(k->rsa, p, q) == 0) + BN_free(d);
+ ? SSH_ERR_LIBCRYPTO_ERROR : 0)) != 0 || + BN_free(iqmp);
+ (r = rsa_generate_additional_parameters(k->rsa, iqmp)) != 0) + BN_free(p);
+ BN_free(q);
+ goto out; + goto out;
+ }
+ if (RSA_set0_factors(k->rsa, p, q) == 0) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ BN_free(p);
+ BN_free(q);
+ goto out;
+ }
+ if (rsa_generate_additional_parameters(k->rsa, iqmp) != 0) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ free(iqmp);
+ goto out;
+ }
+ } + }
break; break;
#endif /* WITH_OPENSSL */ #endif /* WITH_OPENSSL */
@ -3286,7 +3307,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c
/* Check that it is a supported cipher. */ /* Check that it is a supported cipher. */
cipher = cipher_by_number(cipher_type); cipher = cipher_by_number(cipher_type);
@@ -3786,14 +4038,25 @@ sshkey_parse_private_rsa1(struct sshbuf @@ -3786,14 +4038,31 @@ sshkey_parse_private_rsa1(struct sshbuf
} }
/* Read the rest of the private key. */ /* Read the rest of the private key. */
@ -3302,11 +3323,16 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c
+ (r = sshbuf_get_bignum1(decrypted, iqmp)) != 0 || + (r = sshbuf_get_bignum1(decrypted, iqmp)) != 0 ||
+ (r = sshbuf_get_bignum1(decrypted, q)) != 0 || + (r = sshbuf_get_bignum1(decrypted, q)) != 0 ||
+ (r = sshbuf_get_bignum1(decrypted, p)) != 0 || + (r = sshbuf_get_bignum1(decrypted, p)) != 0 ||
+ (RSA_set0_key(prv->rsa, NULL, NULL, d) == 0) || + (RSA_set0_key(prv->rsa, NULL, NULL, d) == 0)) {
+ (RSA_set0_factors(prv->rsa, p, q) == 0)) {
+ BN_free(d); + BN_free(d);
+ BN_free(p); + BN_free(p);
+ BN_free(q); + BN_free(q);
+ BN_free(iqmp);
+ goto out;
+ }
+ if (RSA_set0_factors(prv->rsa, p, q) == 0) {
+ BN_free(p);
+ BN_free(q);
+ BN_free(iqmp); + BN_free(iqmp);
goto out; goto out;
+ } + }
@ -3314,10 +3340,21 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c
/* calculate p-1 and q-1 */ /* calculate p-1 and q-1 */
- if ((r = rsa_generate_additional_parameters(prv->rsa)) != 0) - if ((r = rsa_generate_additional_parameters(prv->rsa)) != 0)
+ if ((r = rsa_generate_additional_parameters(prv->rsa, iqmp)) != 0) + if ((r = rsa_generate_additional_parameters(prv->rsa, iqmp)) != 0)
+ BN_free(iqmp);
goto out; goto out;
/* enable blinding */ /* enable blinding */
@@ -3846,7 +4109,7 @@ sshkey_parse_private_pem_fileblob(struct @@ -3874,7 +4146,9 @@ sshkey_parse_private_pem_fileblob(struct
case EVP_R_BAD_DECRYPT:
r = SSH_ERR_KEY_WRONG_PASSPHRASE;
goto out;
+#ifdef EVP_R_BN_DECODE_ERROR
case EVP_R_BN_DECODE_ERROR:
+#endif
case EVP_R_DECODE_ERROR:
#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
case EVP_R_PRIVATE_KEY_DECODE_ERROR:
@@ -3892,7 +4166,7 @@ sshkey_parse_private_pem_fileblob(struct
r = SSH_ERR_LIBCRYPTO_ERROR; r = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
@ -3640,17 +3677,3 @@ diff -up openssh-7.4p1/ssh-rsa.c.openssl openssh-7.4p1/ssh-rsa.c
sig == NULL || siglen == 0) sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
diff --git a/sshkey.c b/sshkey.c
index ffc17ce..130217a 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -3815,7 +3815,9 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
case EVP_R_BAD_DECRYPT:
r = SSH_ERR_KEY_WRONG_PASSPHRASE;
goto out;
+#ifdef EVP_R_BN_DECODE_ERROR
case EVP_R_BN_DECODE_ERROR:
+#endif
case EVP_R_DECODE_ERROR:
#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
case EVP_R_PRIVATE_KEY_DECODE_ERROR: