Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A heap-buffer-overflow has occurred when running program dec265 in function derive_collocated_motion_vectors at motion.cc #394

Closed
blu3sh0rk opened this issue Feb 22, 2023 · 3 comments

Comments

@blu3sh0rk
Copy link

Desctiption

A heap-buffer-overflow has occurred when running program dec265 in function derive_collocated_motion_vectors at motion.cc:1259:41

Version

dec265  v1.0.11

git log
commit fef32a7761993702c699dfbe3699e44374eb44b5 (HEAD -> master, origin/master, origin/HEAD)
Merge: 3aea5a45 c2b60f1c
Author: Dirk Farin <[email protected]>
Date:   Thu Feb 9 11:13:24 2023 +0100

Steps to reproduce

git clone https://github.com/strukturag/libde265.git
cd libde265
./autogen.sh
export CFLAGS="-g -O0 -lpthread -fsanitize=address"
export CXXFLAGS="-g -O0 -lpthread -fsanitize=address"
export LDFLAGS="-fsanitize=address"
./configure --disable-shared
make -j
cd dec265
./dec265 Heap-overflow-POC1
WARNING: Bit-depth of current image does not match SPS
WARNING: Bit-depth of current image does not match SPS
WARNING: Too many warnings queued
=================================================================
==137060==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000000a8 at pc 0x0000006cc0b4 bp 0x7fff28554e90 sp 0x7fff28554e88
READ of size 8 at 0x6020000000a8 thread T0
    #0 0x6cc0b3 in derive_collocated_motion_vectors(base_context*, de265_image*, slice_segment_header const*, int, int, int, int, int, int, int, MotionVector*, unsigned char*) /home/lzy/fuzz/oss/libde265/libde265/motion.cc:1259:41
    #1 0x6cd4cf in derive_temporal_luma_vector_prediction(base_context*, de265_image*, slice_segment_header const*, int, int, int, int, int, int, MotionVector*, unsigned char*) /home/lzy/fuzz/oss/libde265/libde265/motion.cc:1388:5
    #2 0x6cf16c in get_merge_candidate_list_without_step_9(base_context*, slice_segment_header const*, MotionVectorAccess const&, de265_image*, int, int, int, int, int, int, int, int, int, PBMotion*) /home/lzy/fuzz/oss/libde265/libde265/motion.cc:1523:5
    #3 0x6d052b in derive_luma_motion_merge_mode(base_context*, slice_segment_header const*, de265_image*, int, int, int, int, int, int, int, int, int, PBMotion*) /home/lzy/fuzz/oss/libde265/libde265/motion.cc:1612:3
    #4 0x6d80d6 in motion_vectors_and_ref_indices(base_context*, slice_segment_header const*, de265_image*, PBMotionCoding const&, int, int, int, int, int, int, int, int, PBMotion*) /home/lzy/fuzz/oss/libde265/libde265/motion.cc:2088:7
    #5 0x6d9435 in decode_prediction_unit(base_context*, slice_segment_header const*, de265_image*, PBMotionCoding const&, int, int, int, int, int, int, int, int) /home/lzy/fuzz/oss/libde265/libde265/motion.cc:2171:3
    #6 0x5bf634 in read_prediction_unit(thread_context*, int, int, int, int, int, int, int, int, int) /home/lzy/fuzz/oss/libde265/libde265/slice.cc:4136:3
    #7 0x5c233c in read_coding_unit(thread_context*, int, int, int, int) /home/lzy/fuzz/oss/libde265/libde265/slice.cc:4504:9
    #8 0x5b17db in read_coding_quadtree(thread_context*, int, int, int, int) /home/lzy/fuzz/oss/libde265/libde265/slice.cc:4652:5
    #9 0x5b0887 in read_coding_tree_unit(thread_context*) /home/lzy/fuzz/oss/libde265/libde265/slice.cc:2861:3
    #10 0x5c7fe8 in decode_substream(thread_context*, bool, bool) /home/lzy/fuzz/oss/libde265/libde265/slice.cc:4741:5
    #11 0x5cb648 in read_slice_segment_data(thread_context*) /home/lzy/fuzz/oss/libde265/libde265/slice.cc:5054:14
    #12 0x4e8254 in decoder_context::decode_slice_unit_sequential(image_unit*, slice_unit*) /home/lzy/fuzz/oss/libde265/libde265/decctx.cc:853:7
    #13 0x4e614f in decoder_context::decode_slice_unit_parallel(image_unit*, slice_unit*) /home/lzy/fuzz/oss/libde265/libde265/decctx.cc:955:11    #14 0x4e4b1f in decoder_context::decode_some(bool*) /home/lzy/fuzz/oss/libde265/libde265/decctx.cc:740:13
    #15 0x4e1a3f in decoder_context::read_slice_NAL(bitreader&, NAL_unit*, nal_header&) /home/lzy/fuzz/oss/libde265/libde265/decctx.cc:698:9
    #16 0x4eb7f1 in decoder_context::decode_NAL(NAL_unit*) /home/lzy/fuzz/oss/libde265/libde265/decctx.cc:1240:11
    #17 0x4ec6a1 in decoder_context::decode(int*) /home/lzy/fuzz/oss/libde265/libde265/decctx.cc:1328:16
    #18 0x4d3645 in de265_decode /home/lzy/fuzz/oss/libde265/libde265/de265.cc:367:15
    #19 0x4d0363 in main /home/lzy/fuzz/oss/libde265/dec265/dec265.cc:764:17
    #20 0x7fccbc3e8082 in __libc_start_main /build/glibc-KZwQYS/glibc-2.31/csu/../csu/libc-start.c:308:16
    #21 0x41e5bd in _start (/home/lzy/fuzz/oss/libde265/dec265/dec265+0x41e5bd)

0x6020000000a8 is located 16 bytes to the right of 8-byte region [0x602000000090,0x602000000098)
allocated by thread T0 here:
    #0 0x4ca8dd in operator new(unsigned long) (/home/lzy/fuzz/oss/libde265/dec265/dec265+0x4ca8dd)
    #1 0x500842 in __gnu_cxx::new_allocator<slice_segment_header*>::allocate(unsigned long, void const*) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ext/new_allocator.h:114:27
    #2 0x500751 in std::allocator_traits<std::allocator<slice_segment_header*> >::allocate(std::allocator<slice_segment_header*>&, unsigned long) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/alloc_traits.h:443:20
    #3 0x4ffef1 in std::_Vector_base<slice_segment_header*, std::allocator<slice_segment_header*> >::_M_allocate(unsigned long) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:343:20
    #4 0x4ff227 in void std::vector<slice_segment_header*, std::allocator<slice_segment_header*> >::_M_realloc_insert<slice_segment_header* const&>(__gnu_cxx::__normal_iterator<slice_segment_header**, std::vector<slice_segment_header*, std::allocator<slice_segment_header*> > >, slice_segment_header* const&) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/vector.tcc:440:33
    #5 0x4feea3 in std::vector<slice_segment_header*, std::allocator<slice_segment_header*> >::push_back(slice_segment_header* const&) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:1195:4
    #6 0x4e4066 in de265_image::add_slice_segment_header(slice_segment_header*) /home/lzy/fuzz/oss/libde265/libde265/../libde265/image.h:326:12    #7 0x4e12ba in decoder_context::read_slice_NAL(bitreader&, NAL_unit*, nal_header&) /home/lzy/fuzz/oss/libde265/libde265/decctx.cc:657:14
    #8 0x4eb7f1 in decoder_context::decode_NAL(NAL_unit*) /home/lzy/fuzz/oss/libde265/libde265/decctx.cc:1240:11
    #9 0x4ec6a1 in decoder_context::decode(int*) /home/lzy/fuzz/oss/libde265/libde265/decctx.cc:1328:16
    #10 0x4d3645 in de265_decode /home/lzy/fuzz/oss/libde265/libde265/de265.cc:367:15
    #11 0x4d0363 in main /home/lzy/fuzz/oss/libde265/dec265/dec265.cc:764:17
    #12 0x7fccbc3e8082 in __libc_start_main /build/glibc-KZwQYS/glibc-2.31/csu/../csu/libc-start.c:308:16

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/lzy/fuzz/oss/libde265/libde265/motion.cc:1259:41 in derive_collocated_motion_vectors(base_context*, de265_image*, slice_segment_header const*, int, int, int, int, int, int, int, MotionVector*, unsigned char*)
Shadow bytes around the buggy address:
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff8000: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fa
=>0x0c047fff8010: fa fa 00 fa fa[fa]fd fa fa fa fd fa fa fa fd fa
  0x0c047fff8020: fa fa fd fd fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c047fff8030: fa fa fd fd fa fa fd fa fa fa fd fd fa fa fd fa
  0x0c047fff8040: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c047fff8050: fa fa 04 fa fa fa fd fa fa fa 00 00 fa fa fd fa
  0x0c047fff8060: fa fa 00 fa fa fa 00 00 fa fa 00 00 fa fa 04 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
==137060==ABORTING

POC

https://github.com/blu3sh0rk/Fuzzing-crash/blob/main/Heap-overflow-POC1.zip

Code in function derive_collocated_motion_vectors at motion.cc:1259:41

if (allRefFramesBeforeCurrentFrame) {
      mvCol = mvi.mv[X];
      refIdxCol = mvi.refIdx[X];
      listCol = X;
    }
    else {
      int N = shdr->collocated_from_l0_flag;
      mvCol = mvi.mv[N];
      refIdxCol = mvi.refIdx[N];
      listCol = N;
    }
  }



  1259 const slice_segment_header* colShdr = colImg->slices[ colImg->get_SliceHeaderIndex(xColPb,yColPb) ];

Impact

Potentially causing DoS and RCE

@farindk farindk closed this as completed in d6bf73e Mar 4, 2023
@farindk
Copy link
Contributor

farindk commented Mar 4, 2023

Thank you

@mf1632015
Copy link

This vulnerability has an CVE NO. CVE-2023-27103
Has this been fixed?

@giancorderoortiz
Copy link

giancorderoortiz commented Apr 16, 2023

Could you please generate a new version of this library (i.e. 1.0.12) with the fix in d6bf73e ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants