summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorAdam Langley <agl@chromium.org>2013-02-20 12:42:09 -0500
committerBen Laurie <ben@links.org>2013-06-13 17:10:52 +0100
commit64a786a292e301bfbcb269cd2bff0533503d5b8b (patch)
treee29666df61fdc0bf9a52998f09ad3bcac1b09d4c /ssl
parenta54a61e7a94466f4dc1d663a4297bca562d1a5ac (diff)
Limit the number of empty records that will be processed consecutively
in order to prevent ssl3_get_record from never returning. Reported by "oftc_must_be_destroyed" and George Kadianakis.
Diffstat (limited to 'ssl')
-rw-r--r--ssl/s3_pkt.c19
-rw-r--r--ssl/ssl.h1
-rw-r--r--ssl/ssl_err.c1
3 files changed, 20 insertions, 1 deletions
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index 80562914f0..e589409906 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -272,6 +272,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.
@@ -292,6 +298,7 @@ static int ssl3_get_record(SSL *s)
short version;
unsigned mac_size;
size_t extra;
+ unsigned empty_record_count = 0;
rr= &(s->s3->rrec);
sess=s->session;
@@ -522,7 +529,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;
+ SSLerr(SSL_F_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 67397cf470..845308e2ef 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -2914,6 +2914,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157
#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_TOO_MANY_EMPTY_FRAGMENTS 388
#define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 235
#define SSL_R_UNABLE_TO_DECODE_DH_CERTS 236
#define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS 313
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 2a6ae5b993..e89968c555 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -578,6 +578,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),"tls invalid ecpointformat list"},
{ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST),"tls peer did not respond with certificate list"},
{ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG),"tls rsa encrypted value length is wrong"},
+{ERR_REASON(SSL_R_TOO_MANY_EMPTY_FRAGMENTS),"too many empty fragments"},
{ERR_REASON(SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER),"tried to use unsupported cipher"},
{ERR_REASON(SSL_R_UNABLE_TO_DECODE_DH_CERTS),"unable to decode dh certs"},
{ERR_REASON(SSL_R_UNABLE_TO_DECODE_ECDH_CERTS),"unable to decode ecdh certs"},