0fca960
diff -up openssl-1.0.1e/ssl/d1_both.c.heartbeat openssl-1.0.1e/ssl/d1_both.c
0fca960
--- openssl-1.0.1e/ssl/d1_both.c.heartbeat	2014-04-07 12:52:01.884308971 +0200
0fca960
+++ openssl-1.0.1e/ssl/d1_both.c	2014-04-07 13:04:32.860128295 +0200
0fca960
@@ -1458,26 +1458,36 @@ dtls1_process_heartbeat(SSL *s)
237512d
 	unsigned int payload;
237512d
 	unsigned int padding = 16; /* Use minimum padding */
237512d
 
237512d
-	/* Read type and payload length first */
237512d
-	hbtype = *p++;
237512d
-	n2s(p, payload);
237512d
-	pl = p;
237512d
-
237512d
 	if (s->msg_callback)
237512d
 		s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
237512d
 			&s->s3->rrec.data[0], s->s3->rrec.length,
237512d
 			s, s->msg_callback_arg);
237512d
 
237512d
+	/* Read type and payload length first */
237512d
+	if (1 + 2 + 16 > s->s3->rrec.length)
237512d
+		return 0; /* silently discard */
237512d
+	hbtype = *p++;
237512d
+	n2s(p, payload);
237512d
+	if (1 + 2 + payload + 16 > s->s3->rrec.length)
237512d
+		return 0; /* silently discard per RFC 6520 sec. 4 */
237512d
+	pl = p;
237512d
+
237512d
 	if (hbtype == TLS1_HB_REQUEST)
237512d
 		{
237512d
 		unsigned char *buffer, *bp;
237512d
+		unsigned int write_length = 1 /* heartbeat type */ +
0fca960
+			2 /* heartbeat length */ +
0fca960
+			payload + padding;
237512d
 		int r;
237512d
 
237512d
+		if (write_length > SSL3_RT_MAX_PLAIN_LENGTH)
237512d
+			return 0;
237512d
+
237512d
 		/* Allocate memory for the response, size is 1 byte
237512d
 		 * message type, plus 2 bytes payload length, plus
237512d
 		 * payload, plus padding
237512d
 		 */
237512d
-		buffer = OPENSSL_malloc(1 + 2 + payload + padding);
237512d
+		buffer = OPENSSL_malloc(write_length);
237512d
 		bp = buffer;
237512d
 
237512d
 		/* Enter response type, length and copy payload */
0fca960
@@ -1488,11 +1498,11 @@ dtls1_process_heartbeat(SSL *s)
237512d
 		/* Random padding */
237512d
 		RAND_pseudo_bytes(bp, padding);
237512d
 
237512d
-		r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
237512d
+		r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length);
237512d
 
237512d
 		if (r >= 0 && s->msg_callback)
237512d
 			s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
237512d
-				buffer, 3 + payload + padding,
237512d
+				buffer, write_length,
237512d
 				s, s->msg_callback_arg);
237512d
 
237512d
 		OPENSSL_free(buffer);
0fca960
diff -up openssl-1.0.1e/ssl/t1_lib.c.heartbeat openssl-1.0.1e/ssl/t1_lib.c
0fca960
--- openssl-1.0.1e/ssl/t1_lib.c.heartbeat	2014-04-07 12:52:01.891308997 +0200
0fca960
+++ openssl-1.0.1e/ssl/t1_lib.c	2014-04-07 12:57:45.063603587 +0200
0fca960
@@ -2463,16 +2463,20 @@ tls1_process_heartbeat(SSL *s)
237512d
 	unsigned int payload;
237512d
 	unsigned int padding = 16; /* Use minimum padding */
237512d
 
237512d
-	/* Read type and payload length first */
237512d
-	hbtype = *p++;
237512d
-	n2s(p, payload);
237512d
-	pl = p;
237512d
-
237512d
 	if (s->msg_callback)
237512d
 		s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
237512d
 			&s->s3->rrec.data[0], s->s3->rrec.length,
237512d
 			s, s->msg_callback_arg);
237512d
 
237512d
+	/* Read type and payload length first */
237512d
+	if (1 + 2 + 16 > s->s3->rrec.length)
237512d
+		return 0; /* silently discard */
237512d
+	hbtype = *p++;
237512d
+	n2s(p, payload);
237512d
+	if (1 + 2 + payload + 16 > s->s3->rrec.length)
237512d
+		return 0; /* silently discard per RFC 6520 sec. 4 */
237512d
+	pl = p;
237512d
+
237512d
 	if (hbtype == TLS1_HB_REQUEST)
237512d
 		{
237512d
 		unsigned char *buffer, *bp;