RT3060: Limit the number of empty records.
authorAdam Langley <agl@chromium.org>
Tue, 19 Aug 2014 15:57:53 +0000 (17:57 +0200)
committerEmilia Kasper <emilia@openssl.org>
Fri, 22 Aug 2014 13:53:14 +0000 (15:53 +0200)
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.

Reviewed-by: Bodo Moeller <bodo@openssl.org>
(cherry picked from commit 3aac17a82fbaf2bc23ee62f24611e5883d3e7b97)

ssl/s3_pkt.c

index eff7356a3148207b7eba154de96256ffe630487d..4c9285f355b264e0bed95d2676322176601a1d4e 100644 (file)
@@ -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;
@@ -523,7 +530,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_RECORD_TOO_SMALL);
+                       goto f_err;
+                       }
+               goto again;
+               }
 
 #if 0
 fprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type, rr->length);