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

UBSAN: member access within address … which does not point to an object of type 'xid_count_per_binlog'

    XMLWordPrintable

Details

    Description

      For some reason, I am only seeing this reported for 10.4 and 10.5, not for earlier versions.
      To repeat (I used GCC 9.2.1; clang’s UBSAN would not even bootstrap):

      mkdir build; cd build
      cmake -DCONC_WITH_{UNITTEST,SSL}=OFF -DWITH_EMBEDDED_SERVER=OFF -DWITH_UNIT_TESTS=OFF -DCMAKE_BUILD_TYPE=Debug -DPLUGIN_{ARCHIVE,TOKUDB,MROONGA,OQGRAPH,ROCKSDB,CONNECT,SPIDER}=NO -DWITH_SAFEMALLOC=OFF -DWITH_{SSL,ZLIB}=system "$@" -DCMAKE_C{,XX}_FLAGS='-O2 -march=native' -DWITH_UBSAN=ON ..
      make -j$(nproc)
      cd mysql-test
      nice ./mtr --parallel=$(($(nproc) * 3 / 2)) --force --retry=0 --max-test-fail=0 --big-test
      grep 'log.*runtime error' var/*/log/mysqld*err*|cut -d: -f2-|sed -e 's/0x[0-9a-fA-F]*/0xXXX/'|sort|uniq -c|sort -nr
      

      The top of the output looks like this:

      10.4 576c96a9385f20cf4b6fe685e079dcf8026c3a24

         1740 /mariadb/10.4/sql/log.cc:3812:25: runtime error: member access within address 0xXXX which does not point to an object of type 'xid_count_per_binlog'
         1740 /mariadb/10.4/sql/log.cc:3714:41: runtime error: member access within address 0xXXX which does not point to an object of type 'xid_count_per_binlog'
         1740 /mariadb/10.4/sql/log.cc:3694:29: runtime error: member access within address 0xXXX which does not point to an object of type 'xid_count_per_binlog'
      

      For some reason, not all such access is flagged. Here is a sample around line 3694:

              if (!(new_xid_list_entry = (xid_count_per_binlog *)
                    my_multi_malloc(MYF(MY_WME),
                                    &entry_mem, sizeof(xid_count_per_binlog),
                                    &name_mem, len,
                                    NULL)))
                goto err;
              memcpy(name_mem, log_file_name+off, len);
              new_xid_list_entry->binlog_name= name_mem;
              new_xid_list_entry->binlog_name_len= (int)len;
              new_xid_list_entry->xid_count= 0;
              new_xid_list_entry->notify_count= 0;
      

      The problem appears to be that no constructor for xid_count_per_binlog is being called, and thus the vtable will not be initialized. It looks like there is no constructor at all provided for xid_count_per_binlog, even though it is a derived class:

        struct xid_count_per_binlog : public ilink {
          xid_count_per_binlog();   /* Give link error if constructor used. */
        };
      

      A definition of MYSQL_BIN_LOG::xid_count_per_binlog::xid_count_per_binlog() is nowhere to be seen. Side note: starting with 10.4, we could use the standard C++11 way to omit default member functions:

          xid_count_per_binlog() = delete;
      

      Here is an attempted patch, which fails to compile due to missing constructor:

      diff --git a/sql/log.cc b/sql/log.cc
      index 7f632b43cb6..9a5081ab94a 100644
      --- a/sql/log.cc
      +++ b/sql/log.cc
      @@ -3684,13 +3684,13 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
               size_t off= dirname_length(log_file_name);
               size_t len= strlen(log_file_name) - off;
               char *entry_mem, *name_mem;
      -        if (!(new_xid_list_entry = (xid_count_per_binlog *)
      -              my_multi_malloc(MYF(MY_WME),
      -                              &entry_mem, sizeof(xid_count_per_binlog),
      -                              &name_mem, len,
      -                              NULL)))
      +        if (!my_multi_malloc(MYF(MY_WME),
      +                             &entry_mem, sizeof(xid_count_per_binlog),
      +                             &name_mem, len,
      +                             NULL)))
                 goto err;
               memcpy(name_mem, log_file_name+off, len);
      +        new_xid_list_entry = new (entry_mem) xid_count_per_binlog();
               new_xid_list_entry->binlog_name= name_mem;
               new_xid_list_entry->binlog_name_len= (int)len;
               new_xid_list_entry->xid_count= 0;
      

      (Note: my_multi_malloc() would return entry_mem.)

      I do not know why I am not seeing any UBSAN errors reported for sql/log.cc in 10.2 or 10.3. It does not look like the code has changed. So, the affectedVersion and fixVersion may need to be revised.

      Attachments

        Issue Links

          Activity

            People

              sujatha.sivakumar Sujatha Sivakumar (Inactive)
              marko Marko Mäkelä
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

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