pisa-engine/pisa

Address sanitizer error in codec test

Closed this issue · 1 comments

Describe the bug

With address sanitizer on and on Clang 15, test_block_codecs fails.

It seems to have something to do with varintgb_block codec, because it passed if I comment out that test case.

To Reproduce

Steps to reproduce the behavior:

  1. Compile with Clang 15 (and libc++) and -DUSE_SANITIZERS=ON
  2. Run test_block_codecs test.

Error message

=================================================================
==2940381==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x612000001059 at pc 0x00000070668f bp 0x7ffdee08d690 sp 0x7ffdee08d688
READ of size 4 at 0x612000001059 thread T0
    #0 0x70668e in pisa::VarIntGB<false>::decodeGroupVarInt(unsigned char const*, unsigned int*) /home/elshize/dev/pisa/include/pisa/codec/varintgb.hpp:207:18
    #1 0x70668e in pisa::VarIntGB<false>::decodeArray(unsigned char const*, unsigned long, unsigned int*) /home/elshize/dev/pisa/include/pisa/codec/varintgb.hpp:156:67
    #2 0x70668e in pisa::varintgb_block::decode(unsigned char const*, unsigned int*, unsigned int, unsigned long) /home/elshize/dev/pisa/include/pisa/codec/varintgb.hpp:268:36
    #3 0x70668e in void test_block_codec<pisa::varintgb_block>() /home/elshize/dev/pisa/test/test_block_codecs.cpp:37:17
    #4 0x61b116 in ____C_A_T_C_H____T_E_S_T____0() /home/elshize/dev/pisa/test/test_block_codecs.cpp:53:5
    #5 0x5d78f7 in Catch::TestCase::invoke() const /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:14160:15
    #6 0x5d78f7 in Catch::RunContext::invokeActiveTestCase() /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:13020:27
    #7 0x5d533c in Catch::RunContext::runCurrentTest(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>&) /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:12993:17
    #8 0x5d310e in Catch::RunContext::runTest(Catch::TestCase const&) /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:12754:13
    #9 0x5df155 in Catch::(anonymous namespace)::TestGroup::execute() /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:13347:45
    #10 0x5df155 in Catch::Session::runInternal() /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:13553:39
    #11 0x5dca87 in Catch::Session::run() /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:13509:24
    #12 0x61ae49 in int Catch::Session::run<char>(int, char const* const*) /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:13231:30
    #13 0x61ae49 in main /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:17526:29
    #14 0x7fa313f3d50f in __libc_start_call_main (/usr/lib64/libc.so.6+0x2750f) (BuildId: 81daba31ee66dbd63efdc4252a872949d874d136)
    #15 0x7fa313f3d5c8 in __libc_start_main@GLIBC_2.2.5 (/usr/lib64/libc.so.6+0x275c8) (BuildId: 81daba31ee66dbd63efdc4252a872949d874d136)
    #16 0x463db4 in _start (/home/elshize/dev/pisa/build/test/test_block_codecs+0x463db4) (BuildId: 7580953f3b0991a85bbda2c70f2ff41cd2a9a11c)

0x61200000105a is located 0 bytes to the right of 282-byte region [0x612000000f40,0x61200000105a)
allocated by thread T0 here:
    #0 0x55c3e8 in operator new(unsigned long) (/home/elshize/dev/pisa/build/test/test_block_codecs+0x55c3e8) (BuildId: 7580953f3b0991a85bbda2c70f2ff41cd2a9a11c)
    #1 0x7147fc in void* std::__1::__libcpp_operator_new[abi:v15007]<unsigned long>(unsigned long) /usr/bin/../include/c++/v1/new:246:10
    #2 0x7147fc in std::__1::__libcpp_allocate[abi:v15007](unsigned long, unsigned long) /usr/bin/../include/c++/v1/new:272:10
    #3 0x7147fc in std::__1::allocator<unsigned char>::allocate[abi:v15007](unsigned long) /usr/bin/../include/c++/v1/__memory/allocator.h:112:38
    #4 0x7147fc in std::__1::__allocation_result<std::__1::allocator_traits<std::__1::allocator<unsigned char>>::pointer> std::__1::__allocate_at_least[abi:v15007]<std::__1::allocator<unsigned char>>(std::__1::allocator<unsigned char>&, unsigned long) /usr/bin/../include/c++/v1/__memory/allocate_at_least.h:54:19
    #5 0x7147fc in std::__1::__split_buffer<unsigned char, std::__1::allocator<unsigned char>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<unsigned char>&) /usr/bin/../include/c++/v1/__split_buffer:316:29
    #6 0x7147fc in std::__1::enable_if<__is_cpp17_forward_iterator<unsigned char*>::value && is_constructible<unsigned char, std::__1::iterator_traits<unsigned char*>::reference>::value, std::__1::__wrap_iter<unsigned char*>>::type std::__1::vector<unsigned char, std::__1::allocator<unsigned char>>::insert<unsigned char*>(std::__1::__wrap_iter<unsigned char const*>, unsigned char*, unsigned char*) /usr/bin/../include/c++/v1/vector:1937:57
    #7 0x7040e1 in pisa::varintgb_block::encode(unsigned int const*, unsigned int, unsigned long, std::__1::vector<unsigned char, std::__1::allocator<unsigned char>>&) /home/elshize/dev/pisa/include/pisa/codec/varintgb.hpp:258:13
    #8 0x7040e1 in void test_block_codec<pisa::varintgb_block>() /home/elshize/dev/pisa/test/test_block_codecs.cpp:33:13
    #9 0x61b116 in ____C_A_T_C_H____T_E_S_T____0() /home/elshize/dev/pisa/test/test_block_codecs.cpp:53:5
    #10 0x5d78f7 in Catch::TestCase::invoke() const /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:14160:15
    #11 0x5d78f7 in Catch::RunContext::invokeActiveTestCase() /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:13020:27
    #12 0x5d533c in Catch::RunContext::runCurrentTest(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>&) /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:12993:17
    #13 0x5d310e in Catch::RunContext::runTest(Catch::TestCase const&) /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:12754:13
    #14 0x5df155 in Catch::(anonymous namespace)::TestGroup::execute() /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:13347:45
    #15 0x5df155 in Catch::Session::runInternal() /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:13553:39
    #16 0x5dca87 in Catch::Session::run() /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:13509:24
    #17 0x61ae49 in int Catch::Session::run<char>(int, char const* const*) /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:13231:30
    #18 0x61ae49 in main /home/elshize/dev/pisa/external/Catch2/single_include/catch2/catch.hpp:17526:29
    #19 0x7fa313f3d50f in __libc_start_call_main (/usr/lib64/libc.so.6+0x2750f) (BuildId: 81daba31ee66dbd63efdc4252a872949d874d136)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/elshize/dev/pisa/include/pisa/codec/varintgb.hpp:207:18 in pisa::VarIntGB<false>::decodeGroupVarInt(unsigned char const*, unsigned int*)
Shadow bytes around the buggy address:
  0x0c247fff81b0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c247fff81c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c247fff81d0: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
  0x0c247fff81e0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c247fff81f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c247fff8200: 00 00 00 00 00 00 00 00 00 00 00[02]fa fa fa fa
  0x0c247fff8210: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c247fff8220: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c247fff8230: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c247fff8240: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c247fff8250: 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
==2940381==ABORTING

Environment info

Operating System: Fedora 37
Compiler name: Clang
Compiler version: 15

Seems to happen only if trying to write a full block but not when writing fewer values than block capacity. So looks like something on the edge there.