【OpenSSL】Heartbleed漏洞源码分析(2)

--- a/ssl/d1_both.c
+++ b/ssl/d1_both.c
@@ -1459,26 +1459,36 @@ dtls1_process_heartbeat(SSL *s)
        unsigned int payload;
        unsigned int padding = 16; /* Use minimum padding */
 
-      /* Read type and payload length first */
-      hbtype = *p++;
-      n2s(p, payload);
-      pl = p;
-
        if (s->msg_callback)
                s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
                        &s->s3->rrec.data[0], s->s3->rrec.length,
                        s, s->msg_callback_arg);
 
+      /* Read type and payload length first */
+      if (1 + 2 + 16 > s->s3->rrec.length)
+              return 0; /* silently discard */
+      hbtype = *p++;
+      n2s(p, payload);
+      if (1 + 2 + payload + 16 > s->s3->rrec.length)
+              return 0; /* silently discard per RFC 6520 sec. 4 */
+      pl = p;
+
        if (hbtype == TLS1_HB_REQUEST)
                {
                unsigned char *buffer, *bp;
+              unsigned int write_length = 1 /* heartbeat type */ +
+                                          2 /* heartbeat length */ +
+                                          payload + padding;
                int r;
 
+              if (write_length > SSL3_RT_MAX_PLAIN_LENGTH)
+                      return 0;
+
                /* Allocate memory for the response, size is 1 byte
                * message type, plus 2 bytes payload length, plus
                * payload, plus padding
                */
-              buffer = OPENSSL_malloc(1 + 2 + payload + padding);
+              buffer = OPENSSL_malloc(write_length);
                bp = buffer;
 
                /* Enter response type, length and copy payload */
@@ -1489,11 +1499,11 @@ dtls1_process_heartbeat(SSL *s)
                /* Random padding */
                RAND_pseudo_bytes(bp, padding);
 
-              r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
+              r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length);
 
                if (r >= 0 && s->msg_callback)
                        s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
-                              buffer, 3 + payload + padding,
+                              buffer, write_length,
                                s, s->msg_callback_arg);
 
                OPENSSL_free(buffer);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/ccee2a78f28053c4d030c482de1fc3f2.html