Skip to content
  • Neha Kumari's avatar
    75294736
    Bug#29417234:CONTRIBUTION BY FACEBOOK: FIX WRITING FORMAT DESCRIPTION EVENT · 75294736
    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.7 mysqld generates a FDE
    with 38 types while 8.0 mysqld generates a FDE with 39 types. When 8.0 mysqld
    attempts to read a 5.7 generated FDE and then rewrite out the 5.7 FDE, it
    uses its own value of LOG_EVENT_TYPES (39) to determine the length of the
    array, which is actually only 38 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.
    
    RB: 21788
    75294736
    Bug#29417234:CONTRIBUTION BY FACEBOOK: FIX WRITING FORMAT DESCRIPTION EVENT
    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.7 mysqld generates a FDE
    with 38 types while 8.0 mysqld generates a FDE with 39 types. When 8.0 mysqld
    attempts to read a 5.7 generated FDE and then rewrite out the 5.7 FDE, it
    uses its own value of LOG_EVENT_TYPES (39) to determine the length of the
    array, which is actually only 38 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.
    
    RB: 21788
Loading