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

ASAN use-after-poison after a MY_ROOT_USE_VMEM memory root block is unmapped while poisoned

    XMLWordPrintable

Details

    • Bug
    • Status: Open (View Workflow)
    • Minor
    • Resolution: Unresolved
    • 13.2
    • None
    • Memory management, Server
    • None
    • Linux, ASAN+UBSAN debug build of main (c894d97781), GCC 11.5.0 (libasan.so.6), mtr

    Description

      In an ASAN build, TRASH_MEM() (TRASH_FREE(), that is MEM_NOACCESS()) poisons the unused part of a memory root block: alloc_root() does this for each new block and makes only the pieces it returns addressable again, so the redzones and the unused rest stay poisoned. For a memory root with ROOT_FLAG_VMEM (MY_ROOT_USE_VMEM, for example THD::user_vars_memroot since MDEV-40337), free_root() then returns the blocks with root_free(), which calls my_virtual_mem_release(), that is munmap(), without making them addressable again. The ASAN runtime we use (libasan.so.6 from GCC 11.5) keeps the poison in its shadow memory for that address range. When a later mmap() gets the same addresses, ASAN reports a use-after-poison on valid memory. (Newer ASAN runtimes may clear the shadow in their own munmap() interceptor; we did not try one.)

      On an ASAN build of main,

      ./mtr innodb_fts.fulltext_left_join innodb_fts.fulltext_misc
      

      fails in innodb_fts.fulltext_misc with a use-after-poison in __interceptor_memcpy at 0x7fcc33800020. The same run fails the same way on an ASAN build of our MDEV-10267 branch (main plus our patches, which do not change any file in this stack). There the statement is "SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)" and the stack is:

      ERROR: AddressSanitizer: use-after-poison on address 0x77886a600020
      READ of size 42 at 0x77886a600020 thread T12
          #0 __interceptor_memcpy
          #1 _ma_mmap_pread storage/maria/ma_dynrec.c:143
          #2 _ma_read_static_record storage/maria/ma_statrec.c:190
          #3 _ma_read_rnd_static_record storage/maria/ma_statrec.c:278
          #4 maria_scan storage/maria/ma_scan.c:55
          #5 ha_maria::rnd_next(unsigned char*) storage/maria/ha_maria.cc:2647
      Address 0x77886a600020 is a wild pointer.
      

      Each test passes when it runs alone. In parallel innodb_fts runs it depends on which tests a worker ran before: two parallel runs on main did not show it, two on the branch build (which has a few more innodb_fts tests) did, and one of them also had the same kind of report for INSTALL PLUGIN simple_parser in innodb_fts.plugin_debug, on a global variable of mypluglib.so that had been loaded at such an address:

      ERROR: AddressSanitizer: use-after-poison on address 0x7f94721e77c0
      WRITE of size 8 at 0x7f94721e77c0 thread T12
          #0 my_getopt_init_one_value mysys/my_getopt.c:1408
          #1 init_variables mysys/my_getopt.c:1531
          #2 handle_options mysys/my_getopt.c:282
          #3 test_plugin_options sql/sql_plugin.cc:4366
      0x7f94721e77c0 is located 0 bytes inside of global variable 'sysvar_one_value' defined in 'plugin/fulltext/plugin_example.c:222:17'
      

      With

      @@ static void root_free(MEM_ROOT *root, void *ptr, size_t size)
           update_malloc_size(-(longlong) size,
                               MY_TEST(root->flags & ROOT_FLAG_THREAD_SPECIFIC));
      +    MEM_MAKE_ADDRESSABLE(ptr, size);
           my_virtual_mem_release(ptr, size);
      

      the two-test run above passes on main, and on the branch build two parallel runs of the innodb_fts suite show no use-after-poison (only the UBSAN reports in innodb_fts.stopword that are there without this change too). The same could be done in my_virtual_mem_release() itself.

      MDEV-41029 also shows a use-after-poison when a plugin is installed, but that is a different bug: there ignore_db_dirs_append() calls my_free() on the value of the READ_ONLY variable ignore_db_dirs, which since MDEV-40341 is a copy in read_only_root and was not allocated with my_malloc().

      We ran into this while testing fixes for MDEV-10267 in an ASAN build.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              Futureweb Andreas Schnederle-Wagner
              Votes:
              0 Vote for this issue
              Watchers:
              1 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.