Fix Use After Free for large message sizes
[openssl.git] / ssl / statem / statem.c
index 27dd5d62e56b5c61a6ae2f21988ea0002af38650..f00480803c71883712cbe5dcc8e05f1c3907c33f 100644 (file)
@@ -445,6 +445,21 @@ static void init_read_state_machine(SSL *s)
     st->read_state = READ_STATE_HEADER;
 }
 
+static int grow_init_buf(SSL *s, size_t size) {
+
+    size_t msg_offset = (char *)s->init_msg - s->init_buf->data;
+
+    if (!BUF_MEM_grow_clean(s->init_buf, (int)size))
+        return 0;
+
+    if (size < msg_offset)
+        return 0;
+
+    s->init_msg = s->init_buf->data + msg_offset;
+
+    return 1;
+}
+
 /*
  * This function implements the sub-state machine when the message flow is in
  * MSG_FLOW_READING. The valid sub-states and transitions are:
@@ -545,9 +560,8 @@ static SUB_STATE_RETURN read_state_machine(SSL *s)
             /* dtls_get_message already did this */
             if (!SSL_IS_DTLS(s)
                     && s->s3->tmp.message_size > 0
-                    && !BUF_MEM_grow_clean(s->init_buf,
-                                           (int)s->s3->tmp.message_size
-                                           + SSL3_HM_HEADER_LENGTH)) {
+                    && !grow_init_buf(s, s->s3->tmp.message_size
+                                         + SSL3_HM_HEADER_LENGTH)) {
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
                 SSLerr(SSL_F_READ_STATE_MACHINE, ERR_R_BUF_LIB);
                 return SUB_STATE_ERROR;