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

Heap-buffer-overflows in jfif_decode() at jfif.c:552:31 and 552:38 #43

Closed
cemonatk opened this issue Jun 23, 2021 · 1 comment
Closed

Comments

@cemonatk
Copy link

Describe
Two Heap-buffer-overflows were discovered in ffjpeg. The issues are being triggered in function jfif_decode at jfif.c:552:31 and 552:38.

Found by Cem Onat Karagun of Diesec

System info
OS version : Ubuntu 21.04
ffjpeg Version : master 0fa4cf8a86

Reproduce

Compile ffjpeg with address sanitizer.

CCFLAGS = -Wall -g -fsanitize=address 

POC Files:
decode_poc1.zip
decode_poc2.zip

Run POCs with the commands below.

$ ffjpeg -d decode_poc1

$ ffjpeg -d decode_poc2

Asan output-1:

=================================================================
==3469985==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000010 at pc 0x00000030d50c bp 0x7ffc93e360f0 sp 0x7ffc93e360e8
READ of size 4 at 0x602000000010 thread T0
    #0 0x30d50b in jfif_decode /src/src/jfif.c:552:31
    #1 0x3035f0 in main /src/src/ffjpeg.c:24:9
    #2 0x7f3772bef564 in __libc_start_main csu/../csu/libc-start.c:332:16
    #3 0x2515fd in _start (/REDACTED/ffjpeg/src/ffjpeg+0x2515fd)

0x602000000011 is located 0 bytes to the right of 1-byte region [0x602000000010,0x602000000011)
allocated by thread T0 here:
    #0 0x2cc85d in malloc (/REDACTED/ffjpeg/src/ffjpeg+0x2cc85d)
    #1 0x309025 in jfif_decode /src/src/jfif.c:443:21
    #2 0x3035f0 in main /src/src/ffjpeg.c:24:9
    #3 0x7f3772bef564 in __libc_start_main csu/../csu/libc-start.c:332:16

SUMMARY: AddressSanitizer: heap-buffer-overflow /src/src/jfif.c:552:31 in jfif_decode
Shadow bytes around the buggy address:
  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  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[01]fa fa fa 01 fa fa fa 01 fa fa fa fa fa
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: 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:  

Asan output-2:

=================================================================
==3487109==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000010 at pc 0x00000030d52a bp 0x7ffe17b50930 sp 0x7ffe17b50928
READ of size 4 at 0x602000000010 thread T0
    #0 0x30d529 in jfif_decode /src/src/jfif.c:552:38
    #1 0x3035f0 in main /src/src/ffjpeg.c:24:9
    #2 0x7fec13038564 in __libc_start_main csu/../csu/libc-start.c:332:16
    #3 0x2515fd in _start (/REDACTED/ffjpeg/src/ffjpeg+0x2515fd)

0x602000000011 is located 0 bytes to the right of 1-byte region [0x602000000010,0x602000000011)
allocated by thread T0 here:
    #0 0x2cc85d in malloc (/REDACTED/ffjpeg/src/ffjpeg+0x2cc85d)
    #1 0x309068 in jfif_decode /src/src/jfif.c:444:21
    #2 0x3035f0 in main /src/src/ffjpeg.c:24:9
    #3 0x7fec13038564 in __libc_start_main csu/../csu/libc-start.c:332:16

SUMMARY: AddressSanitizer: heap-buffer-overflow /src/src/jfif.c:552:38 in jfif_decode
Shadow bytes around the buggy address:
  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  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[01]fa fa fa 01 fa fa fa fa fa fa fa fa fa
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: 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
==3487109==ABORTING
@Marsman1996
Copy link
Contributor

This issue is the same as #28 (assigned with CVE-2020-23852) and #24 (assigned CVE-2020-13439).

The overflow is caused by the accessing to the memory buffer without checking the boundary.

ffjpeg/src/jfif.c

Lines 550 to 552 in 0fa4cf8

usrc = yuv_datbuf[1] + uy * yuv_stride[1] + ux;
vsrc = yuv_datbuf[2] + vy * yuv_stride[2] + vx;
yuv_to_rgb(*ysrc, *usrc, *vsrc, bdst + 2, bdst + 1, bdst + 0);

ffjpeg access yuv_datbuf[1] with offset uy * yuv_stride[1] + ux without checking whether it is over the buffer size

ffjpeg/src/jfif.c

Lines 443 to 444 in 0fa4cf8

yuv_datbuf[1] = malloc(sizeof(int) * yuv_stride[1] * yuv_height[1]);
yuv_datbuf[2] = malloc(sizeof(int) * yuv_stride[2] * yuv_height[2]);

An ugly solution is to add check before the access, such as

if (usrc >= yuv_datbuf[1] + yuv_stride[1] * yuv_height[1] * sizeof(int)) {
    printf("usrc overflow\n");
    return -1;
}
if (vsrc >= yuv_datbuf[2] + yuv_stride[2] * yuv_height[2] * sizeof(int)) {
    printf("vsrc overflow\n");
    return -1;
}

@cemonatk cemonatk closed this as completed Dec 7, 2021
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

2 participants