### **1. Description**

A `heap-buffer-overflow` has occurred in `derive_spatial_luma_vector_prediction(base_context*, de265_image*, slice_segment_header const*, int, int, int, int, int, int, int, int, int, int, unsigned char*, MotionVector*)` of `libde265/motion.cc:1636:46` when running program `build/dec265/dec265`, this can reproduce on the lattest commit.

### **2.  Software version info**

```shell
$ git log -1
commit a1ac9e0f84be3c5030dfea4b484fb9e140c89549 (HEAD -> master, origin/master, origin/HEAD)
```

```shell
$ ./build/dec265/dec265   
 dec265  v1.0.9
```

### **3. System  version info**

```shell
Ubuntu 20.04.2 LTS
Linux 5.4.0-65-generic
```

### **4. Command**

```shell
./build/dec265/dec265 ./poc1
```

### **5. Result**

```shell
=================================================================
==2029365==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61b000000d1c at pc 0x7f0051192b1e bp 0x7ffc4de06e10 sp 0x7ffc4de06e08
READ of size 4 at 0x61b000000d1c thread T0
    #0 0x7f0051192b1d in derive_spatial_luma_vector_prediction(base_context*, de265_image*, slice_segment_header const*, int, int, int, int, int, int, int, int, int, int, unsigned char*, MotionVector*) /Projects/libde265/libde265/motion.cc:1636:46
    #1 0x7f00511943b5 in fill_luma_motion_vector_predictors(base_context*, slice_segment_header const*, de265_image*, int, int, int, int, int, int, int, int, int, int, MotionVector*) /Projects/libde265/libde265/motion.cc:1905:3
    #2 0x7f00511955a3 in luma_motion_vector_prediction(base_context*, slice_segment_header const*, de265_image*, PBMotionCoding const&, int, int, int, int, int, int, int, int, int, int) /Projects/libde265/libde265/motion.cc:1978:3
    #3 0x7f00511955a3 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*) /Projects/libde265/libde265/motion.cc:2062:19
    #4 0x7f0051195c03 in decode_prediction_unit(base_context*, slice_segment_header const*, de265_image*, PBMotionCoding const&, int, int, int, int, int, int, int, int) /Projects/libde265/libde265/motion.cc:2102:3
    #5 0x7f00511dda7d in read_prediction_unit(thread_context*, int, int, int, int, int, int, int, int, int) /Projects/libde265/libde265/slice.cc:4136:3
    #6 0x7f00511df598 in read_coding_unit(thread_context*, int, int, int, int) /Projects/libde265/libde265/slice.cc:4497:9
    #7 0x7f00511e477b in decode_substream(thread_context*, bool, bool) /Projects/libde265/libde265/slice.cc:4741:5
    #8 0x7f00511e7bfd in read_slice_segment_data(thread_context*) /Projects/libde265/libde265/slice.cc:5054:14
    #9 0x7f0051116148 in decoder_context::decode_slice_unit_sequential(image_unit*, slice_unit*) /Projects/libde265/libde265/decctx.cc:852:7
    #10 0x7f0051113e41 in decoder_context::decode_slice_unit_parallel(image_unit*, slice_unit*) /Projects/libde265/libde265/decctx.cc:954:11
    #11 0x7f0051112a26 in decoder_context::decode_some(bool*) /Projects/libde265/libde265/decctx.cc:739:13
    #12 0x7f005110f138 in decoder_context::read_slice_NAL(bitreader&, NAL_unit*, nal_header&) /Projects/libde265/libde265/decctx.cc:697:9
    #13 0x7f0051118774 in decoder_context::decode_NAL(NAL_unit*) /Projects/libde265/libde265/decctx.cc:1239:11
    #14 0x7f0051119145 in decoder_context::decode(int*) /Projects/libde265/libde265/decctx.cc:1327:16
    #15 0x4cede4 in main /Projects/libde265/dec265/dec265.cc:764:17
    #16 0x7f0050b18082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
    #17 0x41e51d in _start (/Projects/libde265/build/dec265/dec265+0x41e51d)

0x61b000000d1c is located 20 bytes to the right of 1416-byte region [0x61b000000780,0x61b000000d08)
allocated by thread T0 here:
    #0 0x4ca83d in operator new(unsigned long) (/Projects/libde265/build/dec265/dec265+0x4ca83d)
    #1 0x7f005110d9cf in decoder_context::read_slice_NAL(bitreader&, NAL_unit*, nal_header&) /Projects/libde265/libde265/decctx.cc:633:32
    #2 0x7f0051118774 in decoder_context::decode_NAL(NAL_unit*) /Projects/libde265/libde265/decctx.cc:1239:11
    #3 0x7f0051119145 in decoder_context::decode(int*) /Projects/libde265/libde265/decctx.cc:1327:16
    #4 0x4cede4 in main /Projects/libde265/dec265/dec265.cc:764:17
    #5 0x7f0050b18082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16

SUMMARY: AddressSanitizer: heap-buffer-overflow /Projects/libde265/libde265/motion.cc:1636:46 in derive_spatial_luma_vector_prediction(base_context*, de265_image*, slice_segment_header const*, int, int, int, int, int, int, int, int, int, int, unsigned char*, MotionVector*)
Shadow bytes around the buggy address:
  0x0c367fff8150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c367fff8160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c367fff8170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c367fff8180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c367fff8190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c367fff81a0: 00 fa fa[fa]fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c367fff81b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c367fff81c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c367fff81d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c367fff81e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c367fff81f0: 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
==2029365==ABORTING
```

### **6. POC**

Download: [POC1](https://drive.google.com/file/d/1RHKtx-9g0Eci3XkQz18I_IcngA38HyQ2/)


**Report of the Information Security Laboratory of Ocean University of China @OUC_ISLOUC @OUC_Blue_Whale** 

A Heap-buffer-overflow in motion.cc:1636:46 in derive_spatial_luma_vector_prediction
This is a GitHub Issue
repo:libde265
owner:strukturag
Title : A Heap-buffer-overflow in motion.cc:1636:46 in derive_spatial_luma_vector_prediction
Issue date:

--- start body ---
### **1. Description**

A `heap-buffer-overflow` has occurred in `derive_spatial_luma_vector_prediction(base_context*, de265_image*, slice_segment_header const*, int, int, int, int, int, int, int, int, int, int, unsigned char*, MotionVector*)` of `libde265/motion.cc:1636:46` when running program `build/dec265/dec265`, this can reproduce on the lattest commit.

### **2.  Software version info**

```shell
$ git log -1
commit a1ac9e0f84be3c5030dfea4b484fb9e140c89549 (HEAD -> master, origin/master, origin/HEAD)
```

```shell
$ ./build/dec265/dec265   
 dec265  v1.0.9
```

### **3. System  version info**

```shell
Ubuntu 20.04.2 LTS
Linux 5.4.0-65-generic
```

### **4. Command**

```shell
./build/dec265/dec265 ./poc1
```

### **5. Result**

```shell
=================================================================
==2029365==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61b000000d1c at pc 0x7f0051192b1e bp 0x7ffc4de06e10 sp 0x7ffc4de06e08
READ of size 4 at 0x61b000000d1c thread T0
    #0 0x7f0051192b1d in derive_spatial_luma_vector_prediction(base_context*, de265_image*, slice_segment_header const*, int, int, int, int, int, int, int, int, int, int, unsigned char*, MotionVector*) /Projects/libde265/libde265/motion.cc:1636:46
    #1 0x7f00511943b5 in fill_luma_motion_vector_predictors(base_context*, slice_segment_header const*, de265_image*, int, int, int, int, int, int, int, int, int, int, MotionVector*) /Projects/libde265/libde265/motion.cc:1905:3
    #2 0x7f00511955a3 in luma_motion_vector_prediction(base_context*, slice_segment_header const*, de265_image*, PBMotionCoding const&, int, int, int, int, int, int, int, int, int, int) /Projects/libde265/libde265/motion.cc:1978:3
    #3 0x7f00511955a3 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*) /Projects/libde265/libde265/motion.cc:2062:19
    #4 0x7f0051195c03 in decode_prediction_unit(base_context*, slice_segment_header const*, de265_image*, PBMotionCoding const&, int, int, int, int, int, int, int, int) /Projects/libde265/libde265/motion.cc:2102:3
    #5 0x7f00511dda7d in read_prediction_unit(thread_context*, int, int, int, int, int, int, int, int, int) /Projects/libde265/libde265/slice.cc:4136:3
    #6 0x7f00511df598 in read_coding_unit(thread_context*, int, int, int, int) /Projects/libde265/libde265/slice.cc:4497:9
    #7 0x7f00511e477b in decode_substream(thread_context*, bool, bool) /Projects/libde265/libde265/slice.cc:4741:5
    #8 0x7f00511e7bfd in read_slice_segment_data(thread_context*) /Projects/libde265/libde265/slice.cc:5054:14
    #9 0x7f0051116148 in decoder_context::decode_slice_unit_sequential(image_unit*, slice_unit*) /Projects/libde265/libde265/decctx.cc:852:7
    #10 0x7f0051113e41 in decoder_context::decode_slice_unit_parallel(image_unit*, slice_unit*) /Projects/libde265/libde265/decctx.cc:954:11
    #11 0x7f0051112a26 in decoder_context::decode_some(bool*) /Projects/libde265/libde265/decctx.cc:739:13
    #12 0x7f005110f138 in decoder_context::read_slice_NAL(bitreader&, NAL_unit*, nal_header&) /Projects/libde265/libde265/decctx.cc:697:9
    #13 0x7f0051118774 in decoder_context::decode_NAL(NAL_unit*) /Projects/libde265/libde265/decctx.cc:1239:11
    #14 0x7f0051119145 in decoder_context::decode(int*) /Projects/libde265/libde265/decctx.cc:1327:16
    #15 0x4cede4 in main /Projects/libde265/dec265/dec265.cc:764:17
    #16 0x7f0050b18082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
    #17 0x41e51d in _start (/Projects/libde265/build/dec265/dec265+0x41e51d)

0x61b000000d1c is located 20 bytes to the right of 1416-byte region [0x61b000000780,0x61b000000d08)
allocated by thread T0 here:
    #0 0x4ca83d in operator new(unsigned long) (/Projects/libde265/build/dec265/dec265+0x4ca83d)
    #1 0x7f005110d9cf in decoder_context::read_slice_NAL(bitreader&, NAL_unit*, nal_header&) /Projects/libde265/libde265/decctx.cc:633:32
    #2 0x7f0051118774 in decoder_context::decode_NAL(NAL_unit*) /Projects/libde265/libde265/decctx.cc:1239:11
    #3 0x7f0051119145 in decoder_context::decode(int*) /Projects/libde265/libde265/decctx.cc:1327:16
    #4 0x4cede4 in main /Projects/libde265/dec265/dec265.cc:764:17
    #5 0x7f0050b18082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16

SUMMARY: AddressSanitizer: heap-buffer-overflow /Projects/libde265/libde265/motion.cc:1636:46 in derive_spatial_luma_vector_prediction(base_context*, de265_image*, slice_segment_header const*, int, int, int, int, int, int, int, int, int, int, unsigned char*, MotionVector*)
Shadow bytes around the buggy address:
  0x0c367fff8150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c367fff8160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c367fff8170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c367fff8180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c367fff8190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c367fff81a0: 00 fa fa[fa]fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c367fff81b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c367fff81c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c367fff81d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c367fff81e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c367fff81f0: 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
==2029365==ABORTING
```

### **6. POC**

Download: [POC1](https://drive.google.com/file/d/1RHKtx-9g0Eci3XkQz18I_IcngA38HyQ2/)


**Report of the Information Security Laboratory of Ocean University of China @OUC_ISLOUC @OUC_Blue_Whale** 

--- end body ---

A heap-buffer-overflow vulnerability exists in the `derive_spatial_luma_vector_prediction` function of libde265, which can be exploited by providing a specially crafted input file. This can lead to potential memory corruption and application crashes, making it a significant security risk.