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

AddressSanitizer: heap-buffer-overflow in libsnappy, munmap_chunk(): invalid pointer

    XMLWordPrintable

Details

    Description

      The test case is courtesy of Claude, so I've kept its comments in the test as well.

      It was initially concocted to reproduce the obscure failure

      munmap_chunk(): invalid pointer
      261011  1:42:13 [ERROR] /share8t/bld/main-rel/sql/mariadbd got signal 6 ;
      

      which occurs in the concurrent tests on release builds. The test case does reproduce it, and also hits a more distinctive ASAN error, which may have been ignored by the concurrent tests due to an open bug MDEV-39532 (or some other). However, since unlike MDEV-39532 the test case here is apparently deterministic, and the library/stack trace are different, I'll file it separately.

      --source include/have_innodb.inc
      --source include/have_sequence.inc
       
      if (!$PROVIDER_SNAPPY_SO) {
        skip Needs provider_snappy plugin;
      }
       
      # Incompressible pages are written uncompressed
      call mtr.add_suppression("InnoDB: Page compression errors");
       
      # Incompressible data; every byte has bit 1 (0x02) set, so the chunk-size
      # field of the heap chunk that follows the overflowed buffer gets IS_MMAPPED
      --let BLOB_FILE= $MYSQLTEST_VARDIR/tmp/blob.bin
      --perl
      open(F, '>', $ENV{BLOB_FILE}) or die;
      binmode F;
      srand(1);
      print F map { chr(int(rand(256)) | 2) } 1..65536;
      close F;
      EOF
       
      # Not full_crc32: the page_compressed algorithm is taken from
      # innodb_compression_algorithm at the time of the page write
      SET GLOBAL innodb_checksum_algorithm=strict_crc32;
      CREATE TABLE t0 (id INT PRIMARY KEY, a INT, c VARBINARY(4000)) ENGINE=InnoDB PAGE_COMPRESSED=1;
      INSERT INTO t0 SELECT seq, 0, REPEAT('x',4000) FROM seq_1_to_30;
      CREATE TABLE t1 (b LONGBLOB) ENGINE=InnoDB PAGE_COMPRESSED=1;
       
      # Restart, so that no I/O slot has a page-compression buffer yet
      --let $restart_parameters= --innodb-max-dirty-pages-pct=0 --innodb-max-dirty-pages-pct-lwm=0
      --source include/restart_mysqld.inc
       
      --let $wait_condition= SELECT variable_value = 0 FROM information_schema.global_status WHERE variable_name = 'innodb_buffer_pool_pages_dirty'
      --source include/wait_condition.inc
       
      # Two page_compressed pages are written in one flush batch: two I/O slots
      # allocate a page-compression buffer of srv_page_size bytes, as neither
      # provider_lzo nor provider_snappy is loaded. The buffer of the second
      # slot ends up right below the top of the page cleaner's malloc arena.
      SET GLOBAL innodb_max_dirty_pages_pct=90;
      UPDATE t0 SET a=1 WHERE id IN (1,10);
      SET GLOBAL innodb_max_dirty_pages_pct=0;
      --source include/wait_condition.inc
       
      INSTALL SONAME 'provider_snappy';
      SET GLOBAL innodb_compression_algorithm=snappy;
       
      # The flush batch writes the root page of t1 (slot 1) and then a BLOB page
      # (slot 2). snappy_compress() of the BLOB page overruns the 16KiB buffer
      # into the header of its own working memory, which it then frees:
      # munmap_chunk(): invalid pointer
      SET GLOBAL innodb_max_dirty_pages_pct=90;
      --replace_result $BLOB_FILE BLOB_FILE
      eval INSERT INTO t1 VALUES (LOAD_FILE('$BLOB_FILE'));
      SET GLOBAL innodb_max_dirty_pages_pct=0;
      --source include/wait_condition.inc
       
      DROP TABLE t0, t1;
      UNINSTALL SONAME 'provider_snappy';
      --let $restart_parameters=
      --source include/restart_mysqld.inc
      --remove_file $BLOB_FILE
      

      main 9d7ab2c0092df4bc73b64b915464aecf7e5fe6c4

      ==520110==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62d000364000 at pc 0x7fb380e48061 bp 0x77b373e50380 sp 0x77b373e4fb30
      WRITE of size 16347 at 0x62d000364000 thread T4
          #0 0x7fb380e48060 in __interceptor_memcpy ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827
          #1 0x77b36a62fe56 in snappy::internal::CompressFragment(char const*, unsigned long, char*, unsigned short*, int) (/lib/x86_64-linux-gnu/libsnappy.so.1+0x3e56)
          #2 0x77b36a630625 in snappy::Compress(snappy::Source*, snappy::Sink*) (/lib/x86_64-linux-gnu/libsnappy.so.1+0x4625)
          #3 0x77b36a63089e in snappy::RawCompress(char const*, unsigned long, char*, unsigned long*) (/lib/x86_64-linux-gnu/libsnappy.so.1+0x489e)
          #4 0x77b36a62f4dc in snappy_compress (/lib/x86_64-linux-gnu/libsnappy.so.1+0x34dc)
          #5 0x55b21bb8c765 in fil_page_compress_low /data/bld/main-asan-ubsan/storage/innobase/fil/fil0pagecompress.cc:144
          #6 0x55b21bb8cf3a in fil_page_compress_for_non_full_crc32 /data/bld/main-asan-ubsan/storage/innobase/fil/fil0pagecompress.cc:265
          #7 0x55b21bb8dbe6 in fil_page_compress(unsigned char const*, unsigned char*, unsigned int, unsigned long, bool) /data/bld/main-asan-ubsan/storage/innobase/fil/fil0pagecompress.cc:378
          #8 0x55b21b9fc6b5 in buf_page_encrypt /data/bld/main-asan-ubsan/storage/innobase/buf/buf0flu.cc:714
          #9 0x55b21ba00908 in buf_page_t::flush(fil_space_t*) /data/bld/main-asan-ubsan/storage/innobase/buf/buf0flu.cc:881
          #10 0x55b21ba0bab3 in buf_do_flush_list_batch /data/bld/main-asan-ubsan/storage/innobase/buf/buf0flu.cc:1587
          #11 0x55b21ba0c90e in buf_flush_list_holding_mutex /data/bld/main-asan-ubsan/storage/innobase/buf/buf0flu.cc:1644
          #12 0x55b21ba107e1 in buf_flush_page_cleaner /data/bld/main-asan-ubsan/storage/innobase/buf/buf0flu.cc:3039
          #13 0x55b21ba17d74 in void std::__invoke_impl<void, void (*)() noexcept>(std::__invoke_other, void (*&&)() noexcept) /usr/include/c++/12/bits/invoke.h:61
          #14 0x55b21ba17d74 in std::__invoke_result<void (*)() noexcept>::type std::__invoke<void (*)() noexcept>(void (*&&)() noexcept) /usr/include/c++/12/bits/invoke.h:96
          #15 0x55b21ba17d74 in void std::thread::_Invoker<std::tuple<void (*)() noexcept> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/include/c++/12/bits/std_thread.h:252
          #16 0x55b21ba17d74 in std::thread::_Invoker<std::tuple<void (*)() noexcept> >::operator()() /usr/include/c++/12/bits/std_thread.h:259
          #17 0x55b21ba17d74 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)() noexcept> > >::_M_run() /usr/include/c++/12/bits/std_thread.h:210
          #18 0x7fb3802d44a2  (/lib/x86_64-linux-gnu/libstdc++.so.6+0xd44a2)
          #19 0x7fb3804a71f4 in start_thread nptl/pthread_create.c:442
          #20 0x7fb3805278eb in clone3 ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
       
      0x62d000364000 is located 0 bytes to the right of 16384-byte region [0x62d000360000,0x62d000364000)
      allocated by thread T4 here:
          #0 0x7fb380eb7bf8 in __interceptor_memalign ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:99
          #1 0x55b21b9f3a25 in aligned_malloc(unsigned long, unsigned long) /data/bld/main-asan-ubsan/include/aligned.h:26
          #2 0x55b21b9f3a25 in buf_tmp_reserve_compression_buf /data/bld/main-asan-ubsan/storage/innobase/buf/buf0flu.cc:596
          #3 0x55b21b9fc5e0 in buf_page_encrypt /data/bld/main-asan-ubsan/storage/innobase/buf/buf0flu.cc:712
          #4 0x55b21ba00908 in buf_page_t::flush(fil_space_t*) /data/bld/main-asan-ubsan/storage/innobase/buf/buf0flu.cc:881
          #5 0x55b21ba0bab3 in buf_do_flush_list_batch /data/bld/main-asan-ubsan/storage/innobase/buf/buf0flu.cc:1587
          #6 0x55b21ba0c90e in buf_flush_list_holding_mutex /data/bld/main-asan-ubsan/storage/innobase/buf/buf0flu.cc:1644
          #7 0x55b21ba107e1 in buf_flush_page_cleaner /data/bld/main-asan-ubsan/storage/innobase/buf/buf0flu.cc:3039
          #8 0x55b21ba17d74 in void std::__invoke_impl<void, void (*)() noexcept>(std::__invoke_other, void (*&&)() noexcept) /usr/include/c++/12/bits/invoke.h:61
          #9 0x55b21ba17d74 in std::__invoke_result<void (*)() noexcept>::type std::__invoke<void (*)() noexcept>(void (*&&)() noexcept) /usr/include/c++/12/bits/invoke.h:96
          #10 0x55b21ba17d74 in void std::thread::_Invoker<std::tuple<void (*)() noexcept> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/include/c++/12/bits/std_thread.h:252
          #11 0x55b21ba17d74 in std::thread::_Invoker<std::tuple<void (*)() noexcept> >::operator()() /usr/include/c++/12/bits/std_thread.h:259
          #12 0x55b21ba17d74 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)() noexcept> > >::_M_run() /usr/include/c++/12/bits/std_thread.h:210
          #13 0x7fb3802d44a2  (/lib/x86_64-linux-gnu/libstdc++.so.6+0xd44a2)
       
      Thread T4 created by T0 here:
          #0 0x7fb380e49726 in __interceptor_pthread_create ../../../../src/libsanitizer/asan/asan_interceptors.cpp:207
          #1 0x7fb3802d4578 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (/lib/x86_64-linux-gnu/libstdc++.so.6+0xd4578)
          #2 0x55b21ba06128 in buf_flush_page_cleaner_init() /data/bld/main-asan-ubsan/storage/innobase/buf/buf0flu.cc:3113
          #3 0x55b21b7987f5 in srv_start(bool) /data/bld/main-asan-ubsan/storage/innobase/srv/srv0start.cc:1391
          #4 0x55b21afed8cc in innodb_init /data/bld/main-asan-ubsan/storage/innobase/handler/ha_innodb.cc:4465
          #5 0x55b219726864 in ha_initialize_handlerton(void*) /data/bld/main-asan-ubsan/sql/handler.cc:740
          #6 0x55b217f74f9a in plugin_do_initialize /data/bld/main-asan-ubsan/sql/sql_plugin.cc:1464
          #7 0x55b217f8a313 in plugin_initialize /data/bld/main-asan-ubsan/sql/sql_plugin.cc:1518
          #8 0x55b217f93fa2 in plugin_init(int*, char**, int) /data/bld/main-asan-ubsan/sql/sql_plugin.cc:1762
          #9 0x55b217518872 in init_server_components /data/bld/main-asan-ubsan/sql/mysqld.cc:5543
          #10 0x55b217527ae2 in mysqld_main(int, char**) /data/bld/main-asan-ubsan/sql/mysqld.cc:6344
          #11 0x55b2174f6ea1 in main /data/bld/main-asan-ubsan/sql/main.cc:34
          #12 0x7fb380445249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
       
      SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827 in __interceptor_memcpy
      Shadow bytes around the buggy address:
        0x0c5a800647b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
        0x0c5a800647c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
        0x0c5a800647d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
        0x0c5a800647e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
        0x0c5a800647f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      =>0x0c5a80064800:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c5a80064810: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c5a80064820: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c5a80064830: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c5a80064840: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c5a80064850: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      Shadow byte legend (one shadow byte represents 8 application bytes):
        Addressable:           00
        Partially addressable: 01 02 03 04 05 06 07 
        Heap left redzone:       fa
        Freed heap region:       fd
        Stack left redzone:      f1
        Stack mid redzone:       f2
        Stack right redzone:     f3
        Stack after return:      f5
        Stack use after scope:   f8
        Global redzone:          f9
        Global init order:       f6
        Poisoned by user:        f7
        Container overflow:      fc
        Array cookie:            ac
        Intra object redzone:    bb
        ASan internal:           fe
        Left alloca redzone:     ca
        Right alloca redzone:    cb
      ==520110==ABORTING
      

      Attachments

        Issue Links

          Activity

            People

              andrzej.jarzabek Andrzej Jarzabek
              elenst Elena Stepanova
              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.