Uploaded image for project: 'WiredTiger'
  1. WiredTiger
  2. WT-7727

Fix null pointer passed to memcpy() during 'format' test.

    • 2
    • Storage - Ra 2021-06-28, Storage - Ra 2021-07-12
    • Hide
      The C standard states that the behaviour of memcpy and memcmp (and other mem* functions) is undefined when NULL pointers are passed to them. This is the case even if the 'n' count parameter is 0.

      The UBSAN tests were picking up some cases where NULL pointers were being passed into memcpy and memcmp calls. This was occurring sometimes when the 'n' count parameter was 0.

      To address this, conditional guards have been added around the calls to memcpy and memcmp that were generating UBSAN errors to ensure that the 'n' count parameter is greater than 0.
      Show
      The C standard states that the behaviour of memcpy and memcmp (and other mem* functions) is undefined when NULL pointers are passed to them. This is the case even if the 'n' count parameter is 0. The UBSAN tests were picking up some cases where NULL pointers were being passed into memcpy and memcmp calls. This was occurring sometimes when the 'n' count parameter was 0. To address this, conditional guards have been added around the calls to memcpy and memcmp that were generating UBSAN errors to ensure that the 'n' count parameter is greater than 0.

      A bug where a null pointer is passed into memcpy() has been found in the 'format' test when run in Evergreen in the build variant ubuntu1804-ubsam, using the config pasted below. This is potentially a serious issue as calling memcpy() with a null pointer can give undefined behaviour.

      The following is an extract of Evergreen output showing the failure:

      [2021/06/22 05:16:29.763] format.sh: job in /data/mci/5d49c7c8c63c71a223b752e7119cbb67/wiredtiger/test/format/RUNDIR.1 failed
      [2021/06/22 05:16:29.764] t: process 16514 running
      [2021/06/22 05:16:29.764] ../../../test/format/snap.c:174:16: runtime error: null pointer passed as argument 1, which is declared to never be null
      [2021/06/22 05:16:29.764] /usr/include/string.h:43:28: note: nonnull attribute specified here
      [2021/06/22 05:16:29.764] #0 0x46a7ae in snap_track /data/mci/5d49c7c8c63c71a223b752e7119cbb67/wiredtiger/build_posix/test/format/../../../test/format/snap.c:174:9
      [2021/06/22 05:16:29.764] #1 0x44a3b2 in ops /data/mci/5d49c7c8c63c71a223b752e7119cbb67/wiredtiger/build_posix/test/format/../../../test/format/ops.c:882:17
      [2021/06/22 05:16:29.764] #2 0x7f77171e56da in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76da)
      [2021/06/22 05:16:29.764] #3 0x7f771695871e in clone /build/glibc-S9d2JN/glibc-2.27/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:95
      [2021/06/22 05:16:29.765] format.sh: /data/mci/5d49c7c8c63c71a223b752e7119cbb67/wiredtiger/test/format/RUNDIR.1/CONFIG:

        

      The bug is reproducible in Ubuntu 18.04 using the current head of the 'develop' branch as at 24th June (commit https://github.com/wiredtiger/wiredtiger/commit/b648f62e8a7b3d08aa9c7538aa367a8b64c7b28c ).

      Sometimes one error is displayed, and sometime two are displayed. Whether one or two errors are displayed seems to be related to whether the symbolizer can be found or not.

      Example of one error:

      t: process 10448 running
      ../../../test/format/snap.c:174:16: runtime error: null pointer passed as argument 1, which is declared to never be null
      /usr/include/string.h:43:28: note: nonnull attribute specified here
      ==10448==WARNING: invalid path to external symbolizer!
      ==10448==WARNING: Failed to use and restart external symbolizer!
          #0 0x47031e  (/home/ubuntu/wiredtiger/build_posix/test/format/t+0x47031e)
          #1 0x44fee2  (/home/ubuntu/wiredtiger/build_posix/test/format/t+0x44fee2)
          #2 0x7fae29e436da  (/lib/x86_64-linux-gnu/libpthread.so.0+0x76da)
          #3 0x7fae295b671e  (/lib/x86_64-linux-gnu/libc.so.6+0x12171e)
      
      

       

      Example of two errors:

      t: process 11685 running
      ../../../test/format/snap.c:174:16: runtime error: null pointer passed as argument 1, which is declared to never be null
      /usr/include/string.h:43:28: note: nonnull attribute specified here
      ../../../test/format/snap.c:266:27: runtime error: null pointer passed as argument 2, which is declared to never be null
      /usr/include/string.h:64:33: note: nonnull attribute specified here
         1: table, row-store (20 seconds)
      t: successful run completed

       

      Config for 't' used to reproduce the issue: 

      [2021/06/22 05:16:29.777]   # RUN PARAMETERS: V2
      [2021/06/22 05:16:29.777]   ############################################
      [2021/06/22 05:16:29.777]   assert.read_timestamp=0
      [2021/06/22 05:16:29.777]   assert.write_timestamp=0
      [2021/06/22 05:16:29.777]   backup=0
      [2021/06/22 05:16:29.777]   backup.incremental=off
      [2021/06/22 05:16:29.777]   backup.incr_granularity=1811
      [2021/06/22 05:16:29.777]   btree.bitcnt=6
      [2021/06/22 05:16:29.777]   btree.compression=none
      [2021/06/22 05:16:29.777]   btree.dictionary=0
      [2021/06/22 05:16:29.777]   btree.huffman_value=0
      [2021/06/22 05:16:29.777]   btree.internal_key_truncation=1
      [2021/06/22 05:16:29.777]   btree.internal_page_max=13
      [2021/06/22 05:16:29.777]   btree.key_max=100
      [2021/06/22 05:16:29.777]   btree.key_min=25
      [2021/06/22 05:16:29.777]   btree.leaf_page_max=12
      [2021/06/22 05:16:29.777]   btree.memory_page_max=5
      [2021/06/22 05:16:29.777]   btree.prefix=0
      [2021/06/22 05:16:29.777]   btree.prefix_compression=1
      [2021/06/22 05:16:29.777]   btree.prefix_compression_min=0
      [2021/06/22 05:16:29.777]   btree.repeat_data_pct=55
      [2021/06/22 05:16:29.777]   btree.reverse=0
      [2021/06/22 05:16:29.777]   btree.split_pct=95
      [2021/06/22 05:16:29.777]   btree.value_max=1278
      [2021/06/22 05:16:29.777]   btree.value_min=1
      [2021/06/22 05:16:29.777]   cache=50
      [2021/06/22 05:16:29.777]   cache.evict_max=5
      [2021/06/22 05:16:29.777]   cache.minimum=20
      [2021/06/22 05:16:29.777]   checkpoint=on
      [2021/06/22 05:16:29.777]   checkpoint.log_size=76
      [2021/06/22 05:16:29.777]   checkpoint.wait=72
      [2021/06/22 05:16:29.777]   disk.checksum=off
      [2021/06/22 05:16:29.777]   disk.data_extend=0
      [2021/06/22 05:16:29.777]   disk.direct_io=0
      [2021/06/22 05:16:29.777]   disk.encryption=none
      [2021/06/22 05:16:29.777]   disk.firstfit=0
      [2021/06/22 05:16:29.777]   disk.mmap=1
      [2021/06/22 05:16:29.777]   disk.mmap_all=0
      [2021/06/22 05:16:29.777]   format.abort=0
      [2021/06/22 05:16:29.777]   format.independent_thread_rng=1
      [2021/06/22 05:16:29.777]   format.major_timeout=0
      [2021/06/22 05:16:29.777]   import=0
      [2021/06/22 05:16:29.777]   logging=1
      [2021/06/22 05:16:29.777]   logging.archive=1
      [2021/06/22 05:16:29.777]   logging.compression=none
      [2021/06/22 05:16:29.777]   logging.file_max=134185
      [2021/06/22 05:16:29.777]   logging.prealloc=1
      [2021/06/22 05:16:29.777]   lsm.auto_throttle=1
      [2021/06/22 05:16:29.777]   lsm.bloom=1
      [2021/06/22 05:16:29.777]   lsm.bloom_bit_count=34
      [2021/06/22 05:16:29.777]   lsm.bloom_hash_count=13
      [2021/06/22 05:16:29.777]   lsm.bloom_oldest=0
      [2021/06/22 05:16:29.777]   lsm.chunk_size=2
      [2021/06/22 05:16:29.777]   lsm.merge_max=16
      [2021/06/22 05:16:29.777]   lsm.worker_threads=3
      [2021/06/22 05:16:29.777]   ops.alter=0
      [2021/06/22 05:16:29.777]   ops.compaction=0
      [2021/06/22 05:16:29.777]   ops.hs_cursor=1
      [2021/06/22 05:16:29.777]   ops.pct.delete=0
      [2021/06/22 05:16:29.777]   ops.pct.insert=3
      [2021/06/22 05:16:29.777]   ops.pct.modify=63
      [2021/06/22 05:16:29.777]   ops.pct.read=15
      [2021/06/22 05:16:29.777]   ops.pct.write=19
      [2021/06/22 05:16:29.777]   ops.prepare=0
      [2021/06/22 05:16:29.777]   ops.random_cursor=0
      [2021/06/22 05:16:29.777]   ops.salvage=0
      [2021/06/22 05:16:29.777]   ops.truncate=1
      [2021/06/22 05:16:29.777]   ops.verify=1
      [2021/06/22 05:16:29.778]   quiet=1
      [2021/06/22 05:16:29.778]   runs=1
      [2021/06/22 05:16:29.778]   runs.in_memory=0
      [2021/06/22 05:16:29.778]   runs.ops=50000
      [2021/06/22 05:16:29.778]   runs.rows=10000
      [2021/06/22 05:16:29.778]   runs.source=table
      [2021/06/22 05:16:29.778]   runs.threads=4
      [2021/06/22 05:16:29.778]   runs.timer=6
      [2021/06/22 05:16:29.778]   runs.type=row-store
      [2021/06/22 05:16:29.778]   runs.verify_failure_dump=0
      [2021/06/22 05:16:29.778]   statistics=0
      [2021/06/22 05:16:29.778]   statistics.server=0
      [2021/06/22 05:16:29.778]   stress.aggressive_sweep=0
      [2021/06/22 05:16:29.778]   stress.checkpoint=0
      [2021/06/22 05:16:29.778]   stress.checkpoint_prepare=0
      [2021/06/22 05:16:29.778]   stress.hs_checkpoint_delay=0
      [2021/06/22 05:16:29.778]   stress.hs_search=0
      [2021/06/22 05:16:29.778]   stress.hs_sweep=0
      [2021/06/22 05:16:29.778]   stress.split_1=0
      [2021/06/22 05:16:29.778]   stress.split_2=0
      [2021/06/22 05:16:29.778]   stress.split_3=0
      [2021/06/22 05:16:29.778]   stress.split_4=0
      [2021/06/22 05:16:29.778]   stress.split_5=0
      [2021/06/22 05:16:29.778]   stress.split_6=0
      [2021/06/22 05:16:29.778]   stress.split_7=0
      [2021/06/22 05:16:29.778]   stress.split_8=0
      [2021/06/22 05:16:29.778]   transaction.implicit=0
      [2021/06/22 05:16:29.778]   transaction.timestamps=1
      [2021/06/22 05:16:29.778]   wiredtiger.config=
      [2021/06/22 05:16:29.778]   wiredtiger.rwlock=1
      [2021/06/22 05:16:29.778]   wiredtiger.leak_memory=0
      [2021/06/22 05:16:29.778]   ############################################

       

      To build in a VM:

      export PYTHON=python3
      export LD_LIBRARY_PATH=.libs
      export UBSAN_OPTIONS="print_stacktrace=1:external_symbolizer_path=/usr/bin/llvm-symbolizer:detect_leaks=1:halt_on_error=1:disable_coredump=0"
      
      sh reconf && \
       ../configure --enable-silent-rules \
       --enable-strict \
       --enable-diagnostic \
       --disable-static \
       CC="/usr/bin/clang" \
       CFLAGS="-fsanitize=undefined -fno-omit-frame-pointer -g3 -O0 -ggdb"
      make

       

            Assignee:
            jeremy.thorp@mongodb.com Jeremy Thorp
            Reporter:
            jeremy.thorp@mongodb.com Jeremy Thorp
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: