Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-39689

Slave Overflow on Malformed Table_map_log_event

    XMLWordPrintable

Details

    • Can result in hang or crash

    Description

      Similar to MDEV-39672, where mariadb-binlog can overflow and show
      invalid data if a Table_map_log_event field has a corrupted length,
      the slave parsing functions suffer from the same pattern. E.g.
      parse_column_name()

      static bool parse_column_name(MEM_ROOT *root, LEX_CSTRING *name,
                                    unsigned char *field, unsigned int length)
      {
        for (uchar *end= field+length; field < end ; name++)
        {
          uint name_length= net_field_length(&field);
          if (!(name->str= strmake_root(root, (char*) field, name_length)))
            return 1;
          name->length= name_length;
          field+= name_length;
        }
       
        name->str= 0;                                 // End marker
        return 0;
      }
      

      On the slave side, this can result in various different errors, from
      crashes to invalid output in error messages.

      Reproduces with the following MTR test, .cnf, and patch.

      MTR test

      --source include/have_debug.inc
      --source include/have_binlog_format_row.inc
      --source include/master-slave.inc
       
      --connection master
      CREATE TABLE t1 (c1 INT PRIMARY KEY);
       
      --let $saved_dbug= `SELECT @@SESSION.debug_dbug`
      SET @@SESSION.debug_dbug="+d,corrupt_table_map_column_name_length";
      INSERT INTO t1 VALUES (1);
      --source include/save_master_gtid.inc
      SET @@SESSION.debug_dbug=$saved_dbug;
       
      --echo #
      --echo # Slave should error trying to sync up, read the error log to see the
      --echo # exact error
      --connection slave
      --source include/sync_with_master_gtid.inc
      

      .cnf

      !include ../my.cnf
       
      [mysqld.1]
      binlog_row_metadata=FULL
       
      [mysqld.2]
      slave_type_conversions=ERROR_IF_MISSING_FIELD
      

      patch

      diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc
      index 8652888d744..ab8a8591c67 100644
      --- a/sql/log_event_server.cc
      +++ b/sql/log_event_server.cc
      @@ -7133,7 +7133,9 @@ bool Table_map_log_event::init_column_name_field()
         {
           size_t len= m_table->field[i]->field_name.length;
       
      -    store_compressed_length(buf, len);
      +    store_compressed_length(
      +        buf,
      +        DBUG_IF("corrupt_table_map_column_name_length") ? (1 << 10) : len);
           buf.append(m_table->field[i]->field_name.str, len);
         }
         return write_tlv_field(m_metadata_buf, COLUMN_NAME, buf);
      

      with example error:

      2026-05-20 11:03:13 7 [ERROR] Slave SQL: Table structure for binlog event is not compatible with the table definition on this slave: Column 'c' missing from table 'test.t1', Gtid 0-1-2, Internal MariaDB error code: 4254
      

      This example is just for column name, but all other parse_* functions look affected and should be tested/fixed accordingly.

      Note that implementation should wrap validation conditions with unlikely() as explained here.

      Reported by letchu_pkt

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              bnestere Brandon Nesterenko
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.