Skip to content
  • Joao Gramacho's avatar
    a4ddd83e
    BUG#24365972 BINLOG DECODING ISN'T RESILIENT TO CORRUPT BINLOG FILES · a4ddd83e
    Joao Gramacho authored
    Problem
    =======
    
    When facing decoding of corrupt binary log files, server may misbehave
    without detecting the events corruption.
    
    This patch makes MySQL server more resilient to binary log decoding.
    
    rpl.rpl_extra_row_data refactoring
    ==================================
    
    The rpl.rpl_extra_row_data test case does not supported to be tested
    using MTR --debug option.
    
    A small refactoring without need to record a new test case result was
    done in order to fix the issue.
    
    Fixes for events de-serialization and apply
    ===========================================
    
    @libbinlogevents/include/control_events.h
    
    Added a new parameter (remaining_buffer) to read_data_set() and
    (consumable) to read_data_map() functions, to make them avoid reading
    out of buffer limits.
    
    @libbinlogevents/include/statement_events.h
    
    Added a sanity check to available_buffer() function.
    
    @libbinlogevents/src/control_events.cpp
    
    Format_description_event: removed all post_header_len.resize() calls as
    they are not necessary.
    
    XA_prepare_event: added checks to gtrid and bqual lengths.
    
    Transaction_context_event: added a check before reading common content
    and used remaining_buffer when calling read_data_set.
    
    Transaction_context_event::read_data_set: check if is possible to read
    without reading out of buffer limits.
    
    View_change_event: added a check before reading common content and used
    max_cert_info_len as the consumable limit when calling read_data_map.
    
    View_change_event::read_data_map: check if is possible to read without
    reading out of buffer limits.
    
    @libbinlogevents/src/load_data_events.cpp
    
    Load_event::copy_load_event: added a check to table_name length.
    
    @libbinlogevents/src/rows_event.cpp
    
    Table_map_event::Table_map_event: added a check to avoid reading out of
    buffer limits.
    
    Rows_event::Rows_event: added checks to avoid reading out of buffer
    limits and try/catched std::bad_alloc exception possibly thrown by
    row.assign().
    
    Rows_query_event::Rows_query_event: added a check to avoid reading out
    of buffer limits.
    
    @libbinlogevents/src/statement_events.cpp
    
    Query_event::Query_event: added a check to ensure query length is
    respecting event buffer limits.
    
    Query_event::fill_data_buf: added a check for data (database and query)
    lengths.
    
    User_var_event::User_var_event: added checks to avoid reading out of
    buffer limits.
    
    @sql/log_event.h
    
    XA_prepare_log_event constructor: added a sanity check to invalidate the
    event depending on what XA_prepare_event set.
    
    @sql/log_event.cc
    
    Query_log_event::Query_log_event: added a check to query length in the
    sanity check.
    
    Query_log_event::do_apply_event: extended a debug print, added a check
    to character set to determine if it is "parseable" or not, verified if
    database name is valid for system collation.
    
    Start_log_event_v3::do_apply_event: report an error on applying a
    non-supported binary log version.
    
    User_var_log_event::do_apply_event: reported an sanity check error
    properly and added individual sanity checks for variable types that
    expect fixed (or minimum) amount of bytes to be read.
    
    Rows_log_event::do_post_row_operations: added a sanity check to
    m_curr_row, as it should change after a successful call to
    unpack_current_row().
    
    Write_rows_log_event::write_row: added a sanity check to detect "fake"
    empty rows.
    
    Rows_query_log_event::Rows_query_log_event: added a sanity check based
    on what was provided by Rows_query_event.
    
    Transaction_context_log_event::~Transaction_context_log_event: free only
    if allocated.
    
    @sql/log_event_old.cc
    
    Old_rows_log_event::Old_rows_log_event: added a sanity check to avoid
    reading out of buffer limits.
    
    BUG#27267180 MY_LOCALE_ERRMSGS::LOOKUP RETURNS BAD POINTER FOR INVALID
                 ERROR CODE < 1000
    ======================================================================
    
    When an error code < 1000 is passed as parameter to the function, it
    returns a bad pointer instead of returning the pointer to the "Invalid
    error code" string.
    
    This patch fixes this issue by testing also if the parameter is inside
    the range of the error section being evaluated.
    a4ddd83e
    BUG#24365972 BINLOG DECODING ISN'T RESILIENT TO CORRUPT BINLOG FILES
    Joao Gramacho authored
    Problem
    =======
    
    When facing decoding of corrupt binary log files, server may misbehave
    without detecting the events corruption.
    
    This patch makes MySQL server more resilient to binary log decoding.
    
    rpl.rpl_extra_row_data refactoring
    ==================================
    
    The rpl.rpl_extra_row_data test case does not supported to be tested
    using MTR --debug option.
    
    A small refactoring without need to record a new test case result was
    done in order to fix the issue.
    
    Fixes for events de-serialization and apply
    ===========================================
    
    @libbinlogevents/include/control_events.h
    
    Added a new parameter (remaining_buffer) to read_data_set() and
    (consumable) to read_data_map() functions, to make them avoid reading
    out of buffer limits.
    
    @libbinlogevents/include/statement_events.h
    
    Added a sanity check to available_buffer() function.
    
    @libbinlogevents/src/control_events.cpp
    
    Format_description_event: removed all post_header_len.resize() calls as
    they are not necessary.
    
    XA_prepare_event: added checks to gtrid and bqual lengths.
    
    Transaction_context_event: added a check before reading common content
    and used remaining_buffer when calling read_data_set.
    
    Transaction_context_event::read_data_set: check if is possible to read
    without reading out of buffer limits.
    
    View_change_event: added a check before reading common content and used
    max_cert_info_len as the consumable limit when calling read_data_map.
    
    View_change_event::read_data_map: check if is possible to read without
    reading out of buffer limits.
    
    @libbinlogevents/src/load_data_events.cpp
    
    Load_event::copy_load_event: added a check to table_name length.
    
    @libbinlogevents/src/rows_event.cpp
    
    Table_map_event::Table_map_event: added a check to avoid reading out of
    buffer limits.
    
    Rows_event::Rows_event: added checks to avoid reading out of buffer
    limits and try/catched std::bad_alloc exception possibly thrown by
    row.assign().
    
    Rows_query_event::Rows_query_event: added a check to avoid reading out
    of buffer limits.
    
    @libbinlogevents/src/statement_events.cpp
    
    Query_event::Query_event: added a check to ensure query length is
    respecting event buffer limits.
    
    Query_event::fill_data_buf: added a check for data (database and query)
    lengths.
    
    User_var_event::User_var_event: added checks to avoid reading out of
    buffer limits.
    
    @sql/log_event.h
    
    XA_prepare_log_event constructor: added a sanity check to invalidate the
    event depending on what XA_prepare_event set.
    
    @sql/log_event.cc
    
    Query_log_event::Query_log_event: added a check to query length in the
    sanity check.
    
    Query_log_event::do_apply_event: extended a debug print, added a check
    to character set to determine if it is "parseable" or not, verified if
    database name is valid for system collation.
    
    Start_log_event_v3::do_apply_event: report an error on applying a
    non-supported binary log version.
    
    User_var_log_event::do_apply_event: reported an sanity check error
    properly and added individual sanity checks for variable types that
    expect fixed (or minimum) amount of bytes to be read.
    
    Rows_log_event::do_post_row_operations: added a sanity check to
    m_curr_row, as it should change after a successful call to
    unpack_current_row().
    
    Write_rows_log_event::write_row: added a sanity check to detect "fake"
    empty rows.
    
    Rows_query_log_event::Rows_query_log_event: added a sanity check based
    on what was provided by Rows_query_event.
    
    Transaction_context_log_event::~Transaction_context_log_event: free only
    if allocated.
    
    @sql/log_event_old.cc
    
    Old_rows_log_event::Old_rows_log_event: added a sanity check to avoid
    reading out of buffer limits.
    
    BUG#27267180 MY_LOCALE_ERRMSGS::LOOKUP RETURNS BAD POINTER FOR INVALID
                 ERROR CODE < 1000
    ======================================================================
    
    When an error code < 1000 is passed as parameter to the function, it
    returns a bad pointer instead of returning the pointer to the "Invalid
    error code" string.
    
    This patch fixes this issue by testing also if the parameter is inside
    the range of the error section being evaluated.
Loading