diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c index b66f15f1..172573f8 100644 --- a/ssl/s3_pkt.c +++ b/ssl/s3_pkt.c @@ -273,6 +273,12 @@ int ssl3_read_n(SSL *s, int n, int max, int extend) return(n); } +/* MAX_EMPTY_RECORDS defines the number of consecutive, empty records that will + * be processed per call to ssl3_get_record. Without this limit an attacker + * could send empty records at a faster rate than we can process and cause + * ssl3_get_record to loop forever. */ +#define MAX_EMPTY_RECORDS 32 + /* Call this to get a new input record. * It will return <= 0 if more data is needed, normally due to an error * or non-blocking IO. @@ -293,6 +299,7 @@ static int ssl3_get_record(SSL *s) short version; unsigned mac_size, orig_len; size_t extra; + unsigned empty_record_count = 0; rr= &(s->s3->rrec); sess=s->session; @@ -525,7 +532,17 @@ printf("\n"); s->packet_length=0; /* just read a 0 length packet */ - if (rr->length == 0) goto again; + if (rr->length == 0) + { + empty_record_count++; + if (empty_record_count > MAX_EMPTY_RECORDS) + { + al=SSL_AD_UNEXPECTED_MESSAGE; + OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_TOO_MANY_EMPTY_FRAGMENTS); + goto f_err; + } + goto again; + } #if 0 fprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type, rr->length); diff --git a/ssl/ssl.h b/ssl/ssl.h index dac4c3e3..bae6a353 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -2974,5 +2974,6 @@ void ERR_load_SSL_strings(void); #define SSL_R_CERT_CB_ERROR 428 #define SSL_R_DTLS_MESSAGE_TOO_BIG 429 #define SSL_R_INVALID_SRP_USERNAME 430 +#define SSL_R_TOO_MANY_EMPTY_FRAGMENTS 431 #endif diff --git a/ssl/ssl_error.c b/ssl/ssl_error.c index 1d840129..1c0c93b9 100644 --- a/ssl/ssl_error.c +++ b/ssl/ssl_error.c @@ -475,6 +475,7 @@ const ERR_STRING_DATA SSL_error_string_data[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST), "TLS_INVALID_ECPOINTFORMAT_LIST"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST), "TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG), "TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TOO_MANY_EMPTY_FRAGMENTS), "TOO_MANY_EMPTY_FRAGMENTS"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER), "TRIED_TO_USE_UNSUPPORTED_CIPHER"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNABLE_TO_DECODE_DH_CERTS), "UNABLE_TO_DECODE_DH_CERTS"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNABLE_TO_DECODE_ECDH_CERTS), "UNABLE_TO_DECODE_ECDH_CERTS"},