-
Sujatha authored
Problem: ======= SHOW BINLOG EVENTS FROM <"random"-pos> caused a variety of failures as reported in MDEV-18046. They are fixed but that approach is not future-proof as well as is not optimal to create extra check for being constructed event parameters. Analysis: ========= "show binlog events from <pos>" code considers the user given position as a valid event start position. The code starts reading data from this event start position onwards and tries to map it to a set of known events. Each event has a specific event structure and asserts have been added to ensure that, read event data, satisfies the event specific requirements. When a random position is supplied to "show binlog events command" the event structure specific checks will fail and they result in assert. For example: https://jira.mariadb.org/browse/MDEV-18046 In the bug description user executes CREATE TABLE/INSERT and ALTER SQL commands. When a crazy offset like "SHOW BINLOG EVENTS FROM 365" is provided code assumes offset 365 as valid event begin and proceeds to EVENT_LEN_OFFSET reads some random length and comes up with a crazy event which didn't exits in the binary log. In this quoted example scenario, event read at offset 365 is considered as "Update_rows_log_event", which is not present in binary log. Since this is a random event its validation fails and code results in assert/segmentation fault, as shown below. mysqld: /data/src/10.4/sql/log_event.cc:10863: Rows_log_event::Rows_log_event( const char*, uint, const Format_description_log_event*): Assertion `var_header_len >= 2' failed. 181220 15:27:02 [ERROR] mysqld got signal 6 ; #7 0x00007fa0d96abee2 in __assert_fail () from /lib/x86_64-linux-gnu/libc.so.6 #8 0x000055e744ef82de in Rows_log_event::Rows_log_event (this=0x7fa05800d390, buf=0x7fa05800d080 "", event_len=254, description_event=0x7fa058006d60) at /data/src/10.4/sql/log_event.cc:10863 #9 0x000055e744f00cf8 in Update_rows_log_event::Update_rows_log_event Since we are reading random data repeating the same command SHOW BINLOG EVENTS FROM 365 produces different types of crashes with different events. MDEV-18046 reported 10 such crashes. In order to avoid such scenarios user provided starting offset needs to be validated for its correctness. Best way of doing this is to make use of checksums if they are available. MDEV-18046 fix introduced the checksum based validation. The issue still remains in cases where binlog checksums are disabled. Please find the following bug reports. MDEV-22473: binlog.binlog_show_binlog_event_random_pos failed in buildbot, server crashed in read_log_event MDEV-22455: Server crashes in Table_map_log_event, binlog.binlog_invalid_read_in_rotate failed in buildbot Fix: ==== When binlog checksum is disabled, perform scan(via reading event by event), to validate the requested FROM <pos> offset. Starting from offset 4 read the event_length of next_event in the binary log. Using the next_event length advance current offset to point to next event. Repeat this process till the current offset is less than or equal to crazy offset. If current offset is higher than crazy offset provide appropriate invalid input offset error.
873cc1e7