-
Neha Kumari authored
Problem: In the function: Format_description_log_event::write(..) memcpy((char *)buff + ST_COMMON_HEADER_LEN_OFFSET + 1, &post_header_len[0], Binary_log_event::LOG_EVENT_TYPES); This works fine, if the server generating the FDE is the same as the server writing it out (hence post_header_len.size == Binary_log_event::LOG_EVENT_TYPES). However, when we rotate relay logs, we use this function to write out the FDE by using the event obtained from the master directly. If the master is on an older version of MySQL with not as many event types, then this memcpy will read beyond its buffer causing an ASAN failure. Analysis: Different versions of mysqld have different number of binlog event types. The Format_description_event log has an post_header_len whose size is based on the number of events supported by the mysqld version. So a 5.6 mysqld generates a FDE with 35 types while 5.7 mysqld generates a FDE with 38 types. When 5.7 mysqld attempts to read a 5.6 generated FDE and then rewrite out the 5.6 FDE, it uses its own value of LOG_EVENT_TYPES (38) to determine the length of the array, which is actually only 35 types. The copy accesses undefined memory to generate the FDE. Fix: if the post_header_len is greater than Binary_log_event::LOG_EVENT_TYPES, use the sizeof post_header_len vector while writing post_header_len vector, otherwise use Binary_log_event::LOG_EVENT_TYPES. P.S: This patch also corrects another issue which happens while decoding the post_header_len array in FDE. While decoding post_header_len we use the variable number_of_event_types to determine how many bytes to read from the buffer, now at this point the number_of_event_types holds the value which is one more than the actual value. This problem happens because we don't consider the "BINLOG_CHECKSUM_ALG_DESC_LEN" before decoding post_header_len. In 8.0 this issue has already been corrected(WL#11567) so this part of change is just for 5.7. RB: 21849
Neha Kumari authoredProblem: In the function: Format_description_log_event::write(..) memcpy((char *)buff + ST_COMMON_HEADER_LEN_OFFSET + 1, &post_header_len[0], Binary_log_event::LOG_EVENT_TYPES); This works fine, if the server generating the FDE is the same as the server writing it out (hence post_header_len.size == Binary_log_event::LOG_EVENT_TYPES). However, when we rotate relay logs, we use this function to write out the FDE by using the event obtained from the master directly. If the master is on an older version of MySQL with not as many event types, then this memcpy will read beyond its buffer causing an ASAN failure. Analysis: Different versions of mysqld have different number of binlog event types. The Format_description_event log has an post_header_len whose size is based on the number of events supported by the mysqld version. So a 5.6 mysqld generates a FDE with 35 types while 5.7 mysqld generates a FDE with 38 types. When 5.7 mysqld attempts to read a 5.6 generated FDE and then rewrite out the 5.6 FDE, it uses its own value of LOG_EVENT_TYPES (38) to determine the length of the array, which is actually only 35 types. The copy accesses undefined memory to generate the FDE. Fix: if the post_header_len is greater than Binary_log_event::LOG_EVENT_TYPES, use the sizeof post_header_len vector while writing post_header_len vector, otherwise use Binary_log_event::LOG_EVENT_TYPES. P.S: This patch also corrects another issue which happens while decoding the post_header_len array in FDE. While decoding post_header_len we use the variable number_of_event_types to determine how many bytes to read from the buffer, now at this point the number_of_event_types holds the value which is one more than the actual value. This problem happens because we don't consider the "BINLOG_CHECKSUM_ALG_DESC_LEN" before decoding post_header_len. In 8.0 this issue has already been corrected(WL#11567) so this part of change is just for 5.7. RB: 21849
Loading