Project: gpac (gpac/gpac), language: c++
Vulnerability instance: gpac.cve-2019-20160
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/gpac/gpac/issues/1334
## Description:
Issue: gpac/gpac#1334
Title: AddressSanitizer: stack-buffer-overflow in av1_parse_tile_group media_tools/av_parsers.c:3845
State: closed
Created by: Clingto
Created at: 2019-11-09 11:22:06+00:00

Issue Body:
System info:  
Ubuntu 16.04.6 LTS, X64, gcc 5.4.0, gpac (latest master 00dfc93)  
Compile Command:
```
$ CC="gcc -fsanitize=address -g" CXX="g++ -fsanitize=address -g" ./configure --static-mp4box
$ make
```
Run Command:
```
$ MP4Box -diso -out /dev/null $POC-new-av1_parse_tile_group
```
POC file:  
https://github.com/Clingto/POC/blob/master/gpac-MP4Box/gpac-00dfc93-crashes/POC-new-av1_parse_tile_group

gdb info:
```C
Program received signal SIGSEGV, Segmentation fault.
0x00000000005a375b in av1_parse_tile_group ()
(gdb) bt
#0  0x00000000005a375b in av1_parse_tile_group ()
#1  0x00000000005ad18b in gf_media_aom_av1_parse_obu ()
#2  0x00000000004fe4ce in av1c_Read ()
#3  0x000000010000100a in ?? ()
#4  0x000000010000100b in ?? ()
#5  0x000000010000100c in ?? ()
#6  0x000000010000100d in ?? ()
#7  0x000000010000100e in ?? ()
#8  0x000000010000100f in ?? ()
#9  0x0000000100001010 in ?? ()
#10 0x0000000100001011 in ?? ()
#11 0x0000000100001012 in ?? ()
#12 0x0000000100001013 in ?? ()
#13 0x0000000100001014 in ?? ()
```
ASAN info:
```C
[33m[iso file] Box "dinf" (start 773) has 20 extra bytes
[0m[31m[iso file] Missing DataInformationBox
[0m[33m[iso file] Box "minf" (start 745) has 458 extra bytes
[0m[33m[iso file] Box "mdia" is larger than container box
[0m[33m[iso file] Track with no sample table !
[0m[33m[iso file] Track with no sample description box !
[0m[33m[iso file] Box "trak" size 264 (start 553) invalid (read 714)
[0m[33m[iso file] Box "svcC" size 60 (start 919) invalid (read 126)
[0m[33m[iso file] Box "avcC" (start 979) has 9 extra bytes
[0m[33m[iso file] Box "avcC" (start 1003) has 81 extra bytes
[0m[33m[iso file] extra box avcC found in avc1, deleting
[0m[32m[iso file] Unknown box type av1C in parent avc1
[0m[32m[iso file] Unknown box type stsz in parent avc1
[0m[32m[iso file] Unknown box type stco in parent avc1
[0m[33m[iso file] Box "UNKN" is larger than container box
[0m[33m[iso file] Box "avc1" size 402 (start 833) invalid (read 414)
[0m[33m[iso file] Box "avc1" is larger than container box
[0m[33m[iso file] Box "stsd" size 162 (start 817) invalid (read 418)
[0m[33m[iso file] Box "avcC" (start 979) has 9 extra bytes
[0m[33m[iso file] Box "avcC" (start 1003) has 81 extra bytes
[0m=================================================================
==25824==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffffff8278 at pc 0x00000082ff06 bp 0x7ffffffef7a0 sp 0x7ffffffef790
WRITE of size 4 at 0x7fffffff8278 thread T0
    #0 0x82ff05 in av1_parse_tile_group media_tools/av_parsers.c:3845
    #1 0x840f2f in av1_parse_frame media_tools/av_parsers.c:3882
    #2 0x840f2f in gf_media_aom_av1_parse_obu media_tools/av_parsers.c:3969
    #3 0x69909c in av1c_Read isomedia/avc_ext.c:2651
    #4 0x6c5114 in gf_isom_box_read isomedia/box_funcs.c:1528
    #5 0x6c5114 in gf_isom_box_parse_ex isomedia/box_funcs.c:208
    #6 0x6c5974 in gf_isom_parse_root_box isomedia/box_funcs.c:42
    #7 0x6da6a0 in gf_isom_parse_movie_boxes isomedia/isom_intern.c:206
    #8 0x6dd2f3 in gf_isom_parse_movie_boxes isomedia/isom_intern.c:194
    #9 0x6dd2f3 in gf_isom_open_file isomedia/isom_intern.c:615
    #10 0x42f88a in mp4boxMain /home/aota09/yyp/fuzzcompare/test/gpac/test-crash/build_asan_00dfc93/applications/mp4box/main.c:4767
    #11 0x7ffff638082f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #12 0x41e228 in _start (/home/aota09/yyp/fuzzcompare/test/gpac/test-crash/bin_asan/bin/MP4Box+0x41e228)

Address 0x7fffffff8278 is located in stack of thread T0 at offset 35160 in frame
    #0 0x69889f in av1c_Read isomedia/avc_ext.c:2608

  This frame has 3 object(s):
    [32, 36) 'obu_type'
    [96, 104) 'obu_size'
    [160, 35112) 'state' <== Memory access at offset 35160 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow media_tools/av_parsers.c:3845 av1_parse_tile_group
Shadow bytes around the buggy address:
  0x10007fff6ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff7000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff7010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff7020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff7030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10007fff7040: 00 00 00 00 00 00 00 00 00 f4 f4 f4 f3 f3 f3[f3]
  0x10007fff7050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
  0x10007fff7060: f1 f1 00 00 f4 f4 f3 f3 f3 f3 00 00 00 00 00 00
  0x10007fff7070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff7080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff7090: 00 00 f1 f1 f1 f1 04 f4 f4 f4 f2 f2 f2 f2 04 f4
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
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  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
==25824==ABORTING
```
---
Edit

This bug issue still exists in latest version 0.8.0: 4c19ae5 and 0.9.0: 1de1f8d

---

Addition: This bug was found with our fuzzer, which is based on AFL. Our fuzzer is developed by Yuanpingyu(cfenicey@gmail.com) 、Yanhao and Marsman1996(lqliuyuwei@outlook.com)


Comments:
Comment by carnil on 2019-12-31 10:05:16+00:00:
CVE-2019-20160 was assigned for this issue.

---

Comment by aureliendavid on 2020-01-08 12:45:14+00:00:
Thanks for the report. 

This should be fixed in master / 0.8.0 as of the above commit. 

It will be included in filters / 0.9.0 in the next merge. 

Feel free to reopen the issue if necessary.

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
./configure --static-build --extra-cflags="${CFLAGS}" --extra-ldflags="${CFLAGS}"
make -j$(nproc)

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y build-essential pkg-config libz-dev
RUN git clone https://github.com/gpac/gpac gpac
RUN git -C gpac checkout ed4ec31ea84a1a94abb17669db33f5c4e7a679cf
WORKDIR $SRC/gpac
COPY build.sh $SRC/

Additional files:
filename: fuzz_parse.c
content: /* Copyright 2021 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
      http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <stdio.h>
#include <unistd.h>

#include <gpac/internal/isomedia_dev.h>
#include <gpac/constants.h>

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    char filename[256];
    sprintf(filename, "/tmp/libfuzzer.%d", getpid());

    FILE *fp = fopen(filename, "wb");
    if (!fp) {
        return 0;
    }
    fwrite(data, size, 1, fp);
    fclose(fp);

    GF_ISOFile *movie = NULL;
    movie = gf_isom_open_file(filename, GF_ISOM_OPEN_READ_DUMP, NULL);
    if (movie != NULL) {
        gf_isom_close(movie);
    }
    unlink(filename);
    return 0;
}