]> granicus.if.org Git - php/commitdiff
Fix bug #72293 - Heap overflow in mysqlnd related to BIT fields
authorStanislav Malyshev <stas@php.net>
Tue, 13 Sep 2016 03:25:08 +0000 (20:25 -0700)
committerStanislav Malyshev <stas@php.net>
Tue, 13 Sep 2016 04:04:23 +0000 (21:04 -0700)
ext/mysqlnd/mysqlnd_wireprotocol.c

index 74c97249912d32003fa8200b4c95d9b7e2d5541f..855a25cea1c0b50b535f51e57c7b50eab915c2f7 100644 (file)
@@ -1585,6 +1585,7 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer,
        zend_uchar * p = row_buffer->ptr;
        size_t data_size = row_buffer->app;
        zend_uchar * bit_area = (zend_uchar*) row_buffer->ptr + data_size + 1; /* we allocate from here */
+       const zend_uchar * const packet_end = (zend_uchar*) row_buffer->ptr + data_size;
 
        DBG_ENTER("php_mysqlnd_rowp_read_text_protocol_aux");
 
@@ -1606,8 +1607,13 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer,
                /* Don't reverse the order. It is significant!*/
                zend_uchar *this_field_len_pos = p;
                /* php_mysqlnd_net_field_length() call should be after *this_field_len_pos = p; */
-               unsigned long len = php_mysqlnd_net_field_length(&p);
+               const unsigned long len = php_mysqlnd_net_field_length(&p);
 
+               if (len != MYSQLND_NULL_LENGTH && ((p + len) > packet_end)) {
+                       php_error_docref(NULL, E_WARNING, "Malformed server packet. Field length pointing "MYSQLND_SZ_T_SPEC
+                                                                                         " bytes after end of packet", (p + len) - packet_end - 1);
+                       DBG_RETURN(FAIL);
+               }
                if (copy_data == FALSE && current_field > start_field && last_field_was_string) {
                        /*
                          Normal queries: