Fix small OOB reads.
authorDr. Stephen Henson <steve@openssl.org>
Sat, 17 Sep 2016 11:36:58 +0000 (12:36 +0100)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 21 Sep 2016 13:10:59 +0000 (14:10 +0100)
In ssl3_get_client_certificate, ssl3_get_server_certificate and
ssl3_get_certificate_request check we have enough room
before reading a length.

Thanks to Shi Lei (Gear Team, Qihoo 360 Inc.) for reporting these bugs.

CVE-2016-6306

Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
ssl/s3_clnt.c
ssl/s3_srvr.c

index 36833f7304edfcf3dcbf75c1f75b60665c915eb6..d2afaa5b9f20860fdcda37e2548d54d17a82faa7 100644 (file)
@@ -1216,6 +1216,12 @@ int ssl3_get_server_certificate(SSL *s)
         goto f_err;
     }
     for (nc = 0; nc < llen;) {
+        if (nc + 3 > llen) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
+                   SSL_R_CERT_LENGTH_MISMATCH);
+            goto f_err;
+        }
         n2l3(p, l);
         if ((l + nc + 3) > llen) {
             al = SSL_AD_DECODE_ERROR;
@@ -2171,6 +2177,11 @@ int ssl3_get_certificate_request(SSL *s)
     }
 
     for (nc = 0; nc < llen;) {
+        if (nc + 2 > llen) {
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+            SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG);
+            goto err;
+        }
         n2s(p, l);
         if ((l + nc + 2) > llen) {
             if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG))
index 7c19753853c38d112ad5f7e31cf7d69a3754f57c..01ccd5d2ae78d4403b99d1730be959235a39d2c0 100644 (file)
@@ -3220,6 +3220,12 @@ int ssl3_get_client_certificate(SSL *s)
         goto f_err;
     }
     for (nc = 0; nc < llen;) {
+        if (nc + 3 > llen) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
+                   SSL_R_CERT_LENGTH_MISMATCH);
+            goto f_err;
+        }
         n2l3(p, l);
         if ((l + nc + 3) > llen) {
             al = SSL_AD_DECODE_ERROR;