-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
MDEV-40647 OOB read in IO Thread if the FDEv does not support Rotate Events #5505
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,10 @@ | ||
| SET @saved_dbug= @@GLOBAL.debug_dbug; | ||
| SET @@GLOBAL.debug_dbug= '+d,truncate_fde_at_post_header_len'; | ||
| SET @@GLOBAL.debug_dbug= | ||
| '+d,truncate_fde_post_header_len,truncate_fde_used_checksum_alg'; | ||
| FLUSH BINARY LOGS; | ||
| SHOW BINLOG EVENTS IN 'master-bin.000002'; | ||
| ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error | ||
| SET @@GLOBAL.debug_dbug= '+d,truncate_fde_common_header_len'; | ||
| FLUSH BINARY LOGS; | ||
| SHOW BINLOG EVENTS IN 'master-bin.000003'; | ||
| ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error | ||
| SET @@GLOBAL.debug_dbug= @saved_dbug; | ||
| RESET MASTER; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| SET @saved_dbug= @@GLOBAL.debug_dbug; | ||
| SET @@GLOBAL.debug_dbug= '+d,truncate_fde_post_header_len'; | ||
| include/master-slave.inc | ||
| [connection master] | ||
| FLUSH BINARY LOGS; | ||
| CALL mtr.add_suppression('Found invalid event in binary log'); | ||
| ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error | ||
| connection slave; | ||
| START SLAVE IO_THREAD; | ||
| CALL mtr.add_suppression('Slave I/O: Relay log write failure'); | ||
| include/wait_for_slave_io_error.inc [errno=1595] | ||
| connection master; | ||
| SET @@GLOBAL.debug_dbug= @saved_dbug; | ||
| RESET MASTER; | ||
| connection slave; | ||
| CHANGE MASTER TO master_use_gtid=SLAVE_POS; | ||
| SET @@GLOBAL.gtid_slave_pos=''; | ||
| include/start_slave.inc | ||
| include/rpl_end.inc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| # MDEV-40647 OOB read in IO Thread if the FDEv does not support Rotate Events | ||
|
|
||
| --source include/have_debug.inc | ||
| --source include/have_binlog_format_mixed.inc # should be format-agnostic | ||
|
|
||
| SET @saved_dbug= @@GLOBAL.debug_dbug; | ||
| SET @@GLOBAL.debug_dbug= '+d,truncate_fde_post_header_len'; | ||
| --let $rpl_skip_start_slave= 1 | ||
| # This setup will also RESET MASTER ... | ||
| --source include/master-slave.inc | ||
| # ... which means the binlog file is consistent. | ||
| --let $binlog_file= master-bin.000001 | ||
|
|
||
| # Use a specific binlog position to avoid the | ||
| # test failing early from other metadata events | ||
| --let $binlog_start= query_get_value(SHOW BINLOG STATUS, Position, 1) | ||
| # Generate the Rotate Event | ||
| FLUSH BINARY LOGS; | ||
|
|
||
|
|
||
| # Control: SHOW BINLOG EVENTS fails as expected. | ||
| CALL mtr.add_suppression('Found invalid event in binary log'); | ||
| --disable_query_log | ||
| --error ER_ERROR_WHEN_EXECUTING_COMMAND | ||
| --eval SHOW BINLOG EVENTS IN '$binlog_file' FROM $binlog_start | ||
| --enable_query_log | ||
|
|
||
| --connection slave | ||
| --disable_query_log | ||
| eval CHANGE MASTER TO master_use_gtid=NO, | ||
| master_log_file='$binlog_file', master_log_pos=$binlog_start; | ||
| --enable_query_log | ||
| START SLAVE IO_THREAD; | ||
| CALL mtr.add_suppression('Slave I/O: Relay log write failure'); | ||
| # ER_SLAVE_RELAY_LOG_WRITE_FAILURE | ||
| --let $slave_io_errno= 1595 | ||
| # Experiment: The IO thread should fail. | ||
| --source include/wait_for_slave_io_error.inc | ||
|
|
||
| # Clean-up | ||
| --connection master | ||
| SET @@GLOBAL.debug_dbug= @saved_dbug; | ||
| RESET MASTER; | ||
|
|
||
| --connection slave | ||
| CHANGE MASTER TO master_use_gtid=SLAVE_POS; # restore the default | ||
| --disable_warnings | ||
| SET @@GLOBAL.gtid_slave_pos=''; # for good measure | ||
| --enable_warnings | ||
| --source include/start_slave.inc | ||
| --source include/rpl_end.inc | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2376,8 +2376,9 @@ bool Format_description_log_event::write() | |
| const size_t buff_size= DBUG_EVALUATE_IF("truncate_fde_common_header_len", | ||
| ST_COMMON_HEADER_LEN_OFFSET, sizeof(buff)); | ||
| size_t rec_size= buff_size + | ||
| DBUG_EVALUATE_IF("truncate_fde_at_post_header_len", 0, | ||
| BINLOG_CHECKSUM_ALG_DESC_LEN + number_of_event_types); | ||
| DBUG_EVALUATE_IF("truncate_fde_post_header_len", 0, number_of_event_types) + | ||
| DBUG_EVALUATE_IF("truncate_fde_used_checksum_alg", 0, | ||
| BINLOG_CHECKSUM_ALG_DESC_LEN); | ||
|
Comment on lines
+2379
to
+2381
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I debated with myself whether to simply set some |
||
| int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version); | ||
| memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN); | ||
| if (!dont_set_created) | ||
|
|
@@ -2416,11 +2417,12 @@ bool Format_description_log_event::write() | |
| checksum_alg= BINLOG_CHECKSUM_ALG_CRC32; // Forcing (V) room to fill anyway | ||
| } | ||
| ret= write_header(rec_size) || | ||
| write_data(buff, buff_size) || | ||
| DBUG_EVALUATE_IF("truncate_fde_at_post_header_len", false, | ||
| write_data(post_header_len, number_of_event_types) || | ||
| write_data(&checksum_byte, sizeof(checksum_byte)) || | ||
| write_footer()); | ||
| write_data(buff, buff_size) || | ||
| DBUG_EVALUATE_IF("truncate_fde_post_header_len", false, | ||
| write_data(post_header_len, number_of_event_types)) || | ||
| DBUG_EVALUATE_IF("truncate_fde_used_checksum_alg", false, | ||
| write_data(&checksum_byte, sizeof(checksum_byte))) || | ||
| write_footer(); | ||
| if (no_checksum) | ||
| checksum_alg= BINLOG_CHECKSUM_ALG_OFF; | ||
| return ret; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6610,6 +6610,17 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len) | |
| goto err; | ||
| case ROTATE_EVENT: | ||
| { | ||
| /* | ||
| It's normally done in Log_event::read_log_event(), | ||
| but we bypass it here because it's expensive and costs dynamic memory. | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The design oversight behind this is that the IO Thread needs to preprocess certain events, but using |
||
| */ | ||
| if (unlikely(ROTATE_EVENT > | ||
| mi->rli.relay_log.description_event_for_queue->number_of_event_types)) | ||
| { | ||
| // The current FDE does not support `ROTATE_EVENT`. | ||
| error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE; | ||
| goto err; | ||
| } | ||
| Rotate_log_event rev(buf, checksum_alg != BINLOG_CHECKSUM_ALG_OFF ? | ||
| event_len - BINLOG_CHECKSUM_LEN : event_len, | ||
| mi->rli.relay_log.description_event_for_queue); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MDEV-40647 requires MSAN to reproduce in CI, but our MSAN CI does not
have_debug.(The alternative is to upload the suspicious binlog the fault injection generates…
Do we want this approach instead?)