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

heap-use-after-free in buf_pool_t::is_block_field()




      mleich found a race condition between buffer pool resizing and an update of the adaptive hash index, while testing MDEV-14425.

      ==3752116==ERROR: AddressSanitizer: heap-use-after-free on address 0x61d00000d300 at pc 0x5588ff9718a7 bp 0x5038216570b0 sp 0x5038216570a0
      READ of size 8 at 0x61d00000d300 thread T26
          #0 0x5588ff9718a6 in buf_pool_t::is_block_field(void const*) const /data/Server/preview-10.8-MDEV-14425-innodbF/storage/innobase/include/buf0buf.h:1308
          #1 0x5588ff97190a in buf_pool_t::is_uncompressed(buf_block_t const*) const /data/Server/preview-10.8-MDEV-14425-innodbF/storage/innobase/include/buf0buf.h:1449
          #2 0x5588ffcd648f in btr_search_update_block_hash_info /data/Server/preview-10.8-MDEV-14425-innodbF/storage/innobase/btr/btr0sea.cc:415

      The function is being called as part of a debug assertion there, so this particular failure only affects debug builds. The culprit (found by setting a hardware watchpoint on the AddressSanitizer reported poison byte and executing reverse-continue in rr) is buffer pool resizing:

      Thread 50 (Thread 3752116.3794577):
      #0  __memset_avx2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:200
      #1  0x00007ff70bf479d9 in ?? () from /lib/x86_64-linux-gnu/libasan.so.5
      #2  0x00007ff70c028799 in free () from /lib/x86_64-linux-gnu/libasan.so.5
      #3  0x00005588ffd17b0b in buf_pool_t::resize (this=0x558901d978c0 <buf_pool>) at /data/Server/preview-10.8-MDEV-14425-innodbF/storage/innobase/buf/buf0buf.cc:1894
      #4  0x00005588ffcf9ab8 in buf_resize_callback () at /data/Server/preview-10.8-MDEV-14425-innodbF/storage/innobase/buf/buf0buf.cc:1989

      During the time of this, the thread that is going to fail is already executing that function:

      Thread 3 (Thread 3752116.3757608):
      #0  0x00005588ff971864 in buf_pool_t::is_block_field (this=0x558901d978c0 <buf_pool>, ptr=0x304715439930) at /data/Server/preview-10.8-MDEV-14425-innodbF/storage/innobase/include/buf0buf.h:1307
      #1  0x00005588ff97190b in buf_pool_t::is_uncompressed (this=0x558901d978c0 <buf_pool>, block=0x304715439930) at /data/Server/preview-10.8-MDEV-14425-innodbF/storage/innobase/include/buf0buf.h:1449
      #2  0x00005588ffcd6490 in btr_search_update_block_hash_info (info=0x61a000553a68, block=0x304715439930) at /data/Server/preview-10.8-MDEV-14425-innodbF/storage/innobase/btr/btr0sea.cc:415

      Most invocations of buf_pool_t::is_uncompressed() are in debug assertions, and this faulty debug assertion was introduced in 10.6.

      MDEV-27058 in 10.6 would allow the buf_pool.is_uncompressed(block) assertions to be rewritten simply as block->page.frame. That would be a null pointer for blocks of ROW_FORMAT=COMPRESSED tables whose uncompressed page frame has been discarded.

      The calls to buf_pool.is_uncompressed() outside assertions seem to be protected correctly by buf_pool.page_hash latch. Those are in Block_hint::buffer_fix_block_if_still_valid() and buf_page_get_low().

      The failing debug assertion was added in MDEV-27058.

      A similar assertion had been added to mtr_t::modify() already in MDEV-22110 (MariaDB Server 10.5.5). That one is best removed.

      This bug only affects debug builds during buffer pool resizing, possibly only when running with ASAN.


        Issue Links



              marko Marko Mäkelä
              marko Marko Mäkelä
              0 Vote for this issue
              2 Start watching this issue



                Git Integration

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