Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Duplicate
-
None
-
None
Description
The Connector/C replication API doesn't validate the structure of the
events that it receives in a number of areas. For example, the
compressed ROWS_EVENT handler at lines 1855-1862 of mariadb_rpl.c.
uint8_t algorithm= 0, header_size= 0;
|
uint32_t uncompressed_len= get_compression_info(ev, &algorithm, &header_size);
|
|
|
if (!(rpl_event->event.rows.row_data = ma_calloc_root(&rpl_event->memroot, uncompressed_len))) |
goto mem_error; |
|
|
if ((uncompress((Bytef*)rpl_event->event.rows.row_data, (uLong *)&uncompressed_len, |
(Bytef*)ev + header_size, (uLongf )len) != Z_OK))
|
here, if the uncompressed_len doesn't align with the actual length of
the event, the server can crash (among other possible behaviors).
Additionally:
- mariadb_rpl_extract_rows() has ~30 unchecked pointer reads against a
heap buffer. The only bounds check is the outer while (pos < end)
loop. Inside, every column read (integer types, BLOBs, VARCHARs)
advances pos without checking against end. - Six or more event parsers compute len = event_length - consumed -
checksum - header. When event_length is smaller than the subtracted
terms, len underflows to near SIZE_MAX. The RPL_CHECK_POS macro casts
to ssize_t, which turns the huge value negative, and positive <
negative is always false. The underflowed length then reaches
uncompress() and memcpy(). - A malicious FORMAT_DESCRIPTION_EVENT with all post_header_len bytes
set to 0 causes RPL_CHECK_POST_HEADER_LEN to skip its check for every
subsequent event type (line 62: if (rpl->post_header_len[(type) - 1])
is false when 0).
Reported by byteoverride