diff options
author | Matt Caswell <matt@openssl.org> | 2016-09-09 10:08:45 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2016-09-22 00:25:58 +0100 |
commit | 2c0d295e26306e15a92eb23a84a1802005c1c137 (patch) | |
tree | 980f27d925ae0f60a87414ad3bfb55698678b304 | |
parent | 151adf2e5cc23284a059e0f155505006a1c9fad9 (diff) |
Fix OCSP Status Request extension unbounded memory growth
A malicious client can send an excessively large OCSP Status Request
extension. If that client continually requests renegotiation,
sending a large OCSP Status Request extension each time, then there will
be unbounded memory growth on the server. This will eventually lead to a
Denial Of Service attack through memory exhaustion. Servers with a
default configuration are vulnerable even if they do not support OCSP.
Builds using the "no-ocsp" build time option are not affected.
I have also checked other extensions to see if they suffer from a similar
problem but I could not find any other issues.
CVE-2016-6304
Issue reported by Shi Lei.
Reviewed-by: Rich Salz <rsalz@openssl.org>
-rw-r--r-- | ssl/t1_lib.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 7680491340..4bc13ca5ce 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1284,6 +1284,23 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, size -= 2; if (dsize > size) goto err; + + /* + * We remove any OCSP_RESPIDs from a previous handshake + * to prevent unbounded memory growth - CVE-2016-6304 + */ + sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, + OCSP_RESPID_free); + if (dsize > 0) { + s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null(); + if (s->tlsext_ocsp_ids == NULL) { + *al = SSL_AD_INTERNAL_ERROR; + return 0; + } + } else { + s->tlsext_ocsp_ids = NULL; + } + while (dsize > 0) { OCSP_RESPID *id; int idsize; @@ -1303,13 +1320,6 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, OCSP_RESPID_free(id); goto err; } - if (!s->tlsext_ocsp_ids - && !(s->tlsext_ocsp_ids = - sk_OCSP_RESPID_new_null())) { - OCSP_RESPID_free(id); - *al = SSL_AD_INTERNAL_ERROR; - return 0; - } if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) { OCSP_RESPID_free(id); *al = SSL_AD_INTERNAL_ERROR; |