luntergroup / octopus

Bayesian haplotype-based mutation calling
MIT License
302 stars 38 forks source link

Somatic model leads to memory corruption #228

Closed jbedo closed 2 years ago

jbedo commented 2 years ago

Describe the bug

Cancer caller leads to memory corruption errors.

Version

$ octopus --version
octopus version 0.7.4
Target: x86_64 Linux 5.10.44
SIMD extension: SSE2
Compiler: GNU 10.3.0
Boost: 1_77

NB: happens also on develop branch.

Command Command line to install octopus:

$ 

Command line to run octopus:

$ octopus -R ref.fa -I *.bam -o out --threads=1 -t /stornext/HPCScratch/bedo.j/nix/store/13l767dh50iszc1nwy7afd7wy3rxj4wl-regions.txt --debug=debug.log -N blood --fast --max-genotypes 1000 --annotations AF

Additional context

I ran ASAN and tracked down the issue, here's the output:

==16763==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300524f1e8 at pc 0x000002974205 bp 0x7ffce8f4e930 sp 0x7ffce8f4e928
WRITE of size 8 at 0x60300524f1e8 thread T0
    #0 0x2974204 in octopus::VcfRecordFactory::make(std::vector<octopus::CallWrapper, std::allocator<octopus::CallWrapper> >&&) const /build/source/src/core/tools/vcf_record_factory.cpp:399
    #1 0xdd5b8c in convert_to_vcf /build/source/src/core/callers/caller.cpp:139
    #2 0xe00861 in octopus::Caller::call(octopus::GenomicRegion const&, octopus::ProgressMeter&) const /build/source/src/core/callers/caller.cpp:197
    #3 0x3b6e84f in run_octopus_on_contig /build/source/src/core/octopus.cpp:485
    #4 0x3b6f321 in run_octopus_single_threaded /build/source/src/core/octopus.cpp:521
    #5 0x3c46b62 in octopus::run_calling(octopus::GenomeCallingComponents&) /build/source/src/core/octopus.cpp:1314
    #6 0x3c46de1 in octopus::run_variant_calling(octopus::GenomeCallingComponents&, octopus::UserCommandInfo) /build/source/src/core/octopus.cpp:1467
    #7 0x3c4782c in octopus::run_octopus(octopus::GenomeCallingComponents&, octopus::UserCommandInfo) /build/source/src/core/octopus.cpp:1694
    #8 0x47eabc in main /build/source/src/main.cpp:98
    #9 0x2ba3dcefe77f in __libc_start_main (/nix/store/wl60dr9p15rwf53gxz61ijgisc1zdjc7-glibc-2.33-59/lib/libc.so.6+0x2777f)
    #10 0x4251b9 in _start (/nix/store/5i7s3fiaqd0r61wlj8sbrwb9qim6aqn5-octopus-0.7.4/bin/octopus+0x4251b9)

0x60300524f1e8 is located 0 bytes to the right of 24-byte region [0x60300524f1d0,0x60300524f1e8)
allocated by thread T0 here:
    #0 0x2ba3dbdc4237 in operator new(unsigned long) (/nix/store/b0p7nvkwxr65q016zsqicrd4bcg5bv1s-gcc-10.3.0-lib/lib/libasan.so.6+0xae237)
    #1 0x291d466 in __gnu_cxx::new_allocator<octopus::Call const*>::allocate(unsigned long, void const*) /nix/store/v819nrv8d33ns36gm4v9vqydq1v95axi-gcc-10.3.0/include/c++/10.3.0/ext/new_allocator.h:115
    #2 0x291d466 in std::allocator_traits<std::allocator<octopus::Call const*> >::allocate(std::allocator<octopus::Call const*>&, unsigned long) /nix/store/v819nrv8d33ns36gm4v9vqydq1v95axi-gcc-10.3.0/include/c++/10.3.0/bits/alloc_traits.h:460
    #3 0x291d466 in std::_Vector_base<octopus::Call const*, std::allocator<octopus::Call const*> >::_M_allocate(unsigned long) /nix/store/v819nrv8d33ns36gm4v9vqydq1v95axi-gcc-10.3.0/include/c++/10.3.0/bits/stl_vector.h:346
    #4 0x291d466 in std::_Vector_base<octopus::Call const*, std::allocator<octopus::Call const*> >::_M_create_storage(unsigned long) /nix/store/v819nrv8d33ns36gm4v9vqydq1v95axi-gcc-10.3.0/include/c++/10.3.0/bits/stl_vector.h:361
    #5 0x291d466 in std::_Vector_base<octopus::Call const*, std::allocator<octopus::Call const*> >::_Vector_base(unsigned long, std::allocator<octopus::Call const*> const&) /nix/store/v819nrv8d33ns36gm4v9vqydq1v95axi-gcc-10.3.0/include/c++/10.3.0/bits/stl_vector.h:305
    #6 0x291d466 in std::vector<octopus::Call const*, std::allocator<octopus::Call const*> >::vector(unsigned long, octopus::Call const* const&, std::allocator<octopus::Call const*> const&) /nix/store/v819nrv8d33ns36gm4v9vqydq1v95axi-gcc-10.3.0/include/c++/10.3.0/bits/stl_vector.h:524
    #7 0x291d466 in void __gnu_cxx::new_allocator<std::vector<octopus::Call const*, std::allocator<octopus::Call const*> > >::construct<std::vector<octopus::Call const*, std::allocator<octopus::Call const*> >, unsigned int const&, decltype(nullptr)>(std::vector<octopus::Call const*, std::allocator<octopus::Call const*> >*, unsigned int const&, decltype(nullptr)&&) /nix/store/v819nrv8d33ns36gm4v9vqydq1v95axi-gcc-10.3.0/include/c++/10.3.0/ext/new_allocator.h:150
    #8 0x291d466 in void std::allocator_traits<std::allocator<std::vector<octopus::Call const*, std::allocator<octopus::Call const*> > > >::construct<std::vector<octopus::Call const*, std::allocator<octopus::Call const*> >, unsigned int const&, decltype(nullptr)>(std::allocator<std::vector<octopus::Call const*, std::allocator<octopus::Call const*> > >&, std::vector<octopus::Call const*, std::allocator<octopus::Call const*> >*, unsigned int const&, decltype(nullptr)&&) /nix/store/v819nrv8d33ns36gm4v9vqydq1v95axi-gcc-10.3.0/include/c++/10.3.0/bits/alloc_traits.h:512
    #9 0x291d466 in void std::vector<std::vector<octopus::Call const*, std::allocator<octopus::Call const*> >, std::allocator<std::vector<octopus::Call const*, std::allocator<octopus::Call const*> > > >::emplace_back<unsigned int const&, decltype(nullptr)>(unsigned int const&, decltype(nullptr)&&) /nix/store/v819nrv8d33ns36gm4v9vqydq1v95axi-gcc-10.3.0/include/c++/10.3.0/bits/vector.tcc:115
    #10 0x2973670 in octopus::VcfRecordFactory::make(std::vector<octopus::CallWrapper, std::allocator<octopus::CallWrapper> >&&) const /build/source/src/core/tools/vcf_record_factory.cpp:391
    #11 0xdd5b8c in convert_to_vcf /build/source/src/core/callers/caller.cpp:139
    #12 0xe00861 in octopus::Caller::call(octopus::GenomicRegion const&, octopus::ProgressMeter&) const /build/source/src/core/callers/caller.cpp:197
    #13 0x3b6e84f in run_octopus_on_contig /build/source/src/core/octopus.cpp:485
    #14 0x3b6f321 in run_octopus_single_threaded /build/source/src/core/octopus.cpp:521
    #15 0x3c46b62 in octopus::run_calling(octopus::GenomeCallingComponents&) /build/source/src/core/octopus.cpp:1314
    #16 0x3c46de1 in octopus::run_variant_calling(octopus::GenomeCallingComponents&, octopus::UserCommandInfo) /build/source/src/core/octopus.cpp:1467
    #17 0x3c4782c in octopus::run_octopus(octopus::GenomeCallingComponents&, octopus::UserCommandInfo) /build/source/src/core/octopus.cpp:1694
    #18 0x47eabc in main /build/source/src/main.cpp:98
    #19 0x2ba3dcefe77f in __libc_start_main (/nix/store/wl60dr9p15rwf53gxz61ijgisc1zdjc7-glibc-2.33-59/lib/libc.so.6+0x2777f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /build/source/src/core/tools/vcf_record_factory.cpp:399 in octopus::VcfRecordFactory::make(std::vector<octopus::CallWrapper, std::allocator<octopus::CallWrapper> >&&) const
Shadow bytes around the buggy address:
  0x0c0680a41de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0680a41df0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0680a41e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0680a41e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0680a41e20: fa fa 00 00 00 00 fa fa fa fa fa fa fa fa fa fa
=>0x0c0680a41e30: fa fa fa fa fa fa fa fa fa fa 00 00 00[fa]fa fa
  0x0c0680a41e40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0680a41e50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0680a41e60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0680a41e70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0680a41e80: 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

Looking at line 399, there is a guard beforehand to prevent buffer overruns (https://github.com/luntergroup/octopus/blob/develop/src/core/tools/vcf_record_factory.cpp#L396), but the condition looks to me like it should be prev_represented.back().size() <= i. Of course, this probably doesn't solve the underyling issue since it will just throw an error instead.