libLAS / libLAS

C++ library and programs for reading and writing ASPRS LAS format with LiDAR data

Home Page:http://liblas.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[BUG] 2 buffer overflow in latest liblas

kdsjZh opened this issue · comments

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

las2las.poc.zip

Credit

Han Zheng (NCNIPC of China, Hexhive)