From 6504a2664d3fa8a490cf252b1e48d7b125a912fb Mon Sep 17 00:00:00 2001 From: delphij Date: Wed, 2 Nov 2016 07:09:31 +0000 Subject: [PATCH] Backport OpenSSL commit af58be768ebb690f78530f796e92b8ae5c9a4401: Don't allow too many consecutive warning alerts Certain warning alerts are ignored if they are received. This can mean that no progress will be made if one peer continually sends those warning alerts. Implement a count so that we abort the connection if we receive too many. Issue reported by Shi Lei. This is a direct commit to stable/10 and stable/9. Security: CVE-2016-8610 git-svn-id: svn://svn.freebsd.org/base/stable/10@308200 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- crypto/openssl/ssl/d1_pkt.c | 15 +++++++++++++++ crypto/openssl/ssl/s3_pkt.c | 15 +++++++++++++++ crypto/openssl/ssl/ssl.h | 1 + crypto/openssl/ssl/ssl3.h | 2 ++ crypto/openssl/ssl/ssl_locl.h | 2 ++ 5 files changed, 35 insertions(+) diff --git a/crypto/openssl/ssl/d1_pkt.c b/crypto/openssl/ssl/d1_pkt.c index 086ee9849..868958351 100644 --- a/crypto/openssl/ssl/d1_pkt.c +++ b/crypto/openssl/ssl/d1_pkt.c @@ -924,6 +924,13 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) goto start; } + /* + * Reset the count of consecutive warning alerts if we've got a non-empty + * record that isn't an alert. + */ + if (rr->type != SSL3_RT_ALERT && rr->length != 0) + s->s3->alert_count = 0; + /* we now have a packet which can be read and processed */ if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, @@ -1190,6 +1197,14 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) if (alert_level == SSL3_AL_WARNING) { s->s3->warn_alert = alert_descr; + + s->s3->alert_count++; + if (s->s3->alert_count == MAX_WARN_ALERT_COUNT) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS); + goto f_err; + } + if (alert_descr == SSL_AD_CLOSE_NOTIFY) { #ifndef OPENSSL_NO_SCTP /* diff --git a/crypto/openssl/ssl/s3_pkt.c b/crypto/openssl/ssl/s3_pkt.c index 25cf929a5..cbc348a78 100644 --- a/crypto/openssl/ssl/s3_pkt.c +++ b/crypto/openssl/ssl/s3_pkt.c @@ -1057,6 +1057,13 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) return (ret); } + /* + * Reset the count of consecutive warning alerts if we've got a non-empty + * record that isn't an alert. + */ + if (rr->type != SSL3_RT_ALERT && rr->length != 0) + s->s3->alert_count = 0; + /* we now have a packet which can be read and processed */ if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, @@ -1271,6 +1278,14 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) if (alert_level == SSL3_AL_WARNING) { s->s3->warn_alert = alert_descr; + + s->s3->alert_count++; + if (s->s3->alert_count == MAX_WARN_ALERT_COUNT) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS); + goto f_err; + } + if (alert_descr == SSL_AD_CLOSE_NOTIFY) { s->shutdown |= SSL_RECEIVED_SHUTDOWN; return (0); diff --git a/crypto/openssl/ssl/ssl.h b/crypto/openssl/ssl/ssl.h index 114ee97c7..c15067203 100644 --- a/crypto/openssl/ssl/ssl.h +++ b/crypto/openssl/ssl/ssl.h @@ -2717,6 +2717,7 @@ void ERR_load_SSL_strings(void); # define SSL_R_TLS_HEARTBEAT_PENDING 366 # define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL 367 # define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157 +# define SSL_R_TOO_MANY_WARN_ALERTS 409 # define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233 # define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 234 # define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 235 diff --git a/crypto/openssl/ssl/ssl3.h b/crypto/openssl/ssl/ssl3.h index e9b1170d7..1d50f66a1 100644 --- a/crypto/openssl/ssl/ssl3.h +++ b/crypto/openssl/ssl/ssl3.h @@ -587,6 +587,8 @@ typedef struct ssl3_state_st { char is_probably_safari; # endif /* !OPENSSL_NO_EC */ # endif /* !OPENSSL_NO_TLSEXT */ + /* Count of the number of consecutive warning alerts received */ + unsigned int alert_count; } SSL3_STATE; # endif diff --git a/crypto/openssl/ssl/ssl_locl.h b/crypto/openssl/ssl/ssl_locl.h index 7b1fd1f3b..8ab275592 100644 --- a/crypto/openssl/ssl/ssl_locl.h +++ b/crypto/openssl/ssl/ssl_locl.h @@ -389,6 +389,8 @@ */ # define SSL_MAX_DIGEST 6 +# define MAX_WARN_ALERT_COUNT 5 + # define TLS1_PRF_DGST_MASK (0xff << TLS1_PRF_DGST_SHIFT) # define TLS1_PRF_DGST_SHIFT 10 -- 2.45.0