[BUG] 2 buffer overflow in latest liblas
kdsjZh opened this issue · comments
Han Zheng commented
Summary
Hello, I was testing my fuzzer and found several heap buffer overflows in latest liblas, which can be triggered via ./las2las $POC.
Environment
ubuntu 22.04
clang 12.0.1
libLAS latest version 7a326b1
compile with CC="clang -fsanitize=address -g" and CXX="clang++ -fsanitize=address -g"
Global Overflow
=================================================================
==2510250==ERROR: AddressSanitizer: global-buffer-overflow on address 0x5593cf0f9022 at pc 0x7f6e920ad397 bp 0x7fffb942c8d0 sp 0x7fffb942c078
READ of size 281 at 0x5593cf0f9022 thread T0
#0 0x7f6e920ad396 in __interceptor_memcpy ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827
#1 0x7f6e91e2773d in std::basic_streambuf<char, std::char_traits<char> >::xsputn(char const*, long) (/lib/x86_64-linux-gnu/libstdc++.so.6+0x14a73d)
#2 0x7f6e91e19355 in std::ostream::write(char const*, long) (/lib/x86_64-linux-gnu/libstdc++.so.6+0x13c355)
#3 0x5593cf0b91b9 in void liblas::detail::write_n<char [2]>(std::ostream&, char const (&) [2], long const&) /benchmark/libLAS/include/liblas/detail/private_utility.hpp:391
#4 0x5593cf0b91b9 in liblas::detail::writer::Header::write() /benchmark/libLAS/src/detail/writer/header.cpp:308
#5 0x5593cf0a846f in liblas::detail::WriterImpl::WriteHeader() /benchmark/libLAS/src/detail/writer/writer.cpp:70
#6 0x5593cf08a5b3 in liblas::Writer::Writer(std::ostream&, liblas::Header const&) /benchmark/libLAS/src/writer.cpp:67
#7 0x5593ceef8f27 in start_writer(std::ostream*&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, liblas::Header const&) /benchmark/libLAS/apps/las2las.cpp:40
#8 0x5593ceefa3f2 in process(std::istream&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, liblas::Header&, std::vector<boost::shared_ptr<liblas::FilterI>, std::allocator<boost::shared_ptr<liblas::FilterI> > >&, std::vector<boost::shared_ptr<liblas::TransformI>, std::allocator<boost::shared_ptr<liblas::TransformI> > >&, unsigned int, unsigned int, bool, bool) /benchmark/libLAS/apps/las2las.cpp:117
#9 0x5593ceef3676 in main /benchmark/libLAS/apps/las2las.cpp:371
#10 0x7f6e919d5d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#11 0x7f6e919d5e3f in __libc_start_main_impl ../csu/libc-start.c:392
#12 0x5593ceef6444 in _start (/fuzz/liblas/validate/las2las/las2las+0x7c444)
0x5593cf0f9022 is located 0 bytes to the right of global variable '*.LC14' defined in '/benchmark/libLAS/src/detail/writer/header.cpp' (0x5593cf0f9020) of size 2
SUMMARY: AddressSanitizer: global-buffer-overflow ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827 in __interceptor_memcpy
Shadow bytes around the buggy address:
0x0ab2f9e171b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ab2f9e171c0: 00 02 f9 f9 f9 f9 f9 f9 00 00 00 00 00 00 00 02
0x0ab2f9e171d0: f9 f9 f9 f9 07 f9 f9 f9 f9 f9 f9 f9 00 00 00 00
0x0ab2f9e171e0: 00 00 00 00 05 f9 f9 f9 f9 f9 f9 f9 00 07 f9 f9
0x0ab2f9e171f0: f9 f9 f9 f9 00 00 00 00 00 00 00 00 04 f9 f9 f9
=>0x0ab2f9e17200: f9 f9 f9 f9[02]f9 f9 f9 f9 f9 f9 f9 00 00 00 00
0x0ab2f9e17210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ab2f9e17220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ab2f9e17230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ab2f9e17240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ab2f9e17250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
Shadow gap: cc
==2510250==ABORTING
Heap Overflow
=================================================================
==2576865==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000008536 at pc 0x555e32432feb bp 0x7ffc293c9640 sp 0x7ffc293c9630
READ of size 2 at 0x602000008536 thread T0
#0 0x555e32432fea in liblas::SpatialReference::GetGTIF() /benchmark/libLAS/src/spatialreference.cpp:517
#1 0x555e32435544 in liblas::SpatialReference::SpatialReference(std::vector<liblas::VariableRecord, std::allocator<liblas::VariableRecord> > const&) /benchmark/libLAS/src/spatialreference.cpp:102
#2 0x555e324db527 in liblas::detail::reader::Header::ReadVLRs() /benchmark/libLAS/src/detail/reader/header.cpp:389
#3 0x555e324de296 in liblas::detail::reader::Header::ReadHeader() /benchmark/libLAS/src/detail/reader/header.cpp:272
#4 0x555e323dc422 in liblas::ReaderFactory::CreateWithStream(std::istream&) /benchmark/libLAS/src/factory.cpp:92
#5 0x555e3233f72f in main /benchmark/libLAS/apps/las2las.cpp:331
#6 0x7ff4f224dd8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#7 0x7ff4f224de3f in __libc_start_main_impl ../csu/libc-start.c:392
#8 0x555e32343444 in _start (/fuzz/liblas/validate/las2las/las2las+0x7c444)
0x602000008536 is located 5 bytes to the right of 1-byte region [0x602000008530,0x602000008531)
allocated by thread T0 here:
#0 0x7ff4f29a11c7 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:99
#1 0x555e324325ed in __gnu_cxx::new_allocator<unsigned char>::allocate(unsigned long, void const*) /usr/include/c++/11/ext/new_allocator.h:127
#2 0x555e324325ed in __gnu_cxx::__alloc_traits<std::allocator<unsigned char>, unsigned char>::allocate(std::allocator<unsigned char>&, unsigned long) /usr/include/c++/11/ext/alloc_traits.h:133
#3 0x555e324325ed in std::_Vector_base<unsigned char, std::allocator<unsigned char> >::_M_allocate(unsigned long) /usr/include/c++/11/bits/stl_vector.h:346
#4 0x555e324325ed in std::_Vector_base<unsigned char, std::allocator<unsigned char> >::_M_create_storage(unsigned long) /usr/include/c++/11/bits/stl_vector.h:361
#5 0x555e324325ed in std::_Vector_base<unsigned char, std::allocator<unsigned char> >::_Vector_base(unsigned long, std::allocator<unsigned char> const&) /usr/include/c++/11/bits/stl_vector.h:305
#6 0x555e324325ed in std::vector<unsigned char, std::allocator<unsigned char> >::vector(std::vector<unsigned char, std::allocator<unsigned char> > const&) /usr/include/c++/11/bits/stl_vector.h:555
#7 0x555e324325ed in liblas::SpatialReference::GetGTIF() /benchmark/libLAS/src/spatialreference.cpp:496
#8 0x602000008510 (<unknown module>)
SUMMARY: AddressSanitizer: heap-buffer-overflow /benchmark/libLAS/src/spatialreference.cpp:517 in liblas::SpatialReference::GetGTIF()
Shadow bytes around the buggy address:
0x0c047fff9050: fa fa 00 fa fa fa fd fd fa fa fd fd fa fa 00 fa
0x0c047fff9060: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa fd fd
0x0c047fff9070: fa fa 00 00 fa fa fd fd fa fa 00 00 fa fa fd fd
0x0c047fff9080: fa fa 00 00 fa fa fd fa fa fa fd fa fa fa fd fa
0x0c047fff9090: fa fa fd fa fa fa 01 fa fa fa 01 fa fa fa 00 00
=>0x0c047fff90a0: fa fa 01 fa fa fa[01]fa fa fa fa fa fa fa fa fa
0x0c047fff90b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff90c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff90d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff90e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff90f0: 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
Shadow gap: cc
==2576865==ABORTING
POC
Credit
Han Zheng (NCNIPC of China, Hexhive)