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

Segmentation fault casued by heap use after free using mp4box in mpgviddmx_process, reframe_mpgvid.c:851 #1887

Closed
3 tasks done
5hadowblad3 opened this issue Aug 24, 2021 · 2 comments

Comments

@5hadowblad3
Copy link

  • I looked for a similar issue and couldn't find any.
  • I tried with the latest version of GPAC. Installers available at http://gpac.io/downloads/gpac-nightly-builds/
  • I give enough information for contributors to reproduce my issue (meaningful title, github labels, platform and compiler, command-line ...).

Hi, there.

There is a segmentation fault caused by null pointer dereference in mpgviddmx_process, reframe_mpgvid.c:851 in commit 592ba26.

Here is my environment, compiler info and gpac version:

Distributor ID:	Ubuntu
Description:	Ubuntu 16.04.6 LTS
Release:	16.04
Codename:	xenial
gcc: 5.4.0

MP4Box - GPAC version 1.1.0-DEV-rev1170-g592ba26-master
(c) 2000-2021 Telecom Paris distributed under LGPL v2.1+ - http://gpac.io
	MINI build (encoders, decoders, audio and video output disabled)

Please cite our work in your research:
	GPAC Filters: https://doi.org/10.1145/3339825.3394929
	GPAC: https://doi.org/10.1145/1291233.1291452

GPAC Configuration: --static-bin --enable-debug
Features: GPAC_CONFIG_LINUX GPAC_64_BITS GPAC_HAS_SOCK_UN GPAC_MINIMAL_ODF GPAC_HAS_QJS GPAC_HAS_FREETYPE GPAC_HAS_JPEG GPAC_HAS_PNG  GPAC_DISABLE_3D

To reproduce, run

./MP4Box -info poc

POC:
poc.zip
(unzip first)

Here is the trace reported by gdb:

Stopped reason: SIGSEGV
gef➤  bt
#0  0x0000000000cf5a9b in memcpy ()
#1  0x00000000008a24a7 in mpgviddmx_process (filter=0x124cbd0) at /mnt/data/playground/gpac/src/filters/reframe_mpgvid.c:851
#2  0x00000000007480a0 in gf_filter_process_task (task=0x123a0e0) at /mnt/data/playground/gpac/src/filter_core/filter.c:2441
#3  0x000000000073798c in gf_fs_thread_proc (sess_thread=0x12382b0) at /mnt/data/playground/gpac/src/filter_core/filter_session.c:1640
#4  0x0000000000738305 in gf_fs_run (fsess=0x1238220) at /mnt/data/playground/gpac/src/filter_core/filter_session.c:1877
#5  0x00000000006571ea in gf_media_import (importer=0x7fffffff5c20) at /mnt/data/playground/gpac/src/media_tools/media_import.c:1178
#6  0x000000000042cdf9 in convert_file_info (inName=0x7fffffffe163 "tmp", trackID=0x0) at /mnt/data/playground/gpac/applications/mp4box/fileimport.c:128
#7  0x00000000004168c3 in mp4boxMain (argc=0x3, argv=0x7fffffffdde8) at /mnt/data/playground/gpac/applications/mp4box/main.c:5925
#8  0x0000000000418d6b in main (argc=0x3, argv=0x7fffffffdde8) at /mnt/data/playground/gpac/applications/mp4box/main.c:6455
#9  0x0000000000caaa06 in generic_start_main ()
#10 0x0000000000caaff5 in __libc_start_main ()
#11 0x0000000000403f39 in _start ()

The reason for this bug is that the program does not check the nullity of the pointer before copy memory to it.
image

@5hadowblad3 5hadowblad3 changed the title Segmentation fault casued by null pointer dereference using mp4box in mpgviddmx_process, reframe_mpgvid.c:851 Segmentation fault casued by heap use after free using mp4box in mpgviddmx_process, reframe_mpgvid.c:851 Aug 24, 2021
@5hadowblad3
Copy link
Author

Here is the trace reported by ASAN:

 ==9071==ERROR: AddressSanitizer: heap-use-after-free on address 0x62600001b100 at pc 0x7ff1a2599733 bp 0x7ffe1e68b1f0 sp 0x7ffe1e68a998
 READ of size 10000 at 0x62600001b100 thread T0
     #0 0x7ff1a2599732  (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x79732)
     #1 0x7ff1a0b32e8e in memcpy /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34
     #2 0x7ff1a0b32e8e in mpgviddmx_process /playground/gpac/src/filters/reframe_mpgvid.c:851
     #3 0x7ff1a07e8920 in gf_filter_process_task /playground/gpac/src/filter_core/filter.c:2441
     #4 0x7ff1a07a8a62 in gf_fs_thread_proc /playground/gpac/src/filter_core/filter_session.c:1640
     #5 0x7ff1a07b3930 in gf_fs_run /playground/gpac/src/filter_core/filter_session.c:1877
     #6 0x7ff1a028bc15 in gf_media_import /playground/gpac/src/media_tools/media_import.c:1178
     #7 0x55dfd0ebb72f in convert_file_info /playground/gpac/applications/mp4box/fileimport.c:128
     #8 0x55dfd0e8e515 in mp4boxMain /playground/gpac/applications/mp4box/main.c:5925
     #9 0x7ff19dc3ebf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
     #10 0x55dfd0e6f2d9 in _start (/playground/gpac/build-a/bin/gcc/MP4Box+0x872d9)
 
 0x62600001b100 is located 0 bytes inside of 10000-byte region [0x62600001b100,0x62600001d810)
 freed by thread T0 here:
     #0 0x7ff1a25fef30 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef30)
     #1 0x7ff1a0b32fc5 in mpgviddmx_process /playground/gpac/src/filters/reframe_mpgvid.c:849
     #2 0x7ff1a07e8920 in gf_filter_process_task /playground/gpac/src/filter_core/filter.c:2441
     #3 0x7ff1a07a8a62 in gf_fs_thread_proc /playground/gpac/src/filter_core/filter_session.c:1640
     #4 0x7ff1a07b3930 in gf_fs_run /playground/gpac/src/filter_core/filter_session.c:1877
     #5 0x7ff1a028bc15 in gf_media_import /playground/gpac/src/media_tools/media_import.c:1178
     #6 0x55dfd0ebb72f in convert_file_info /playground/gpac/applications/mp4box/fileimport.c:128
     #7 0x55dfd0e8e515 in mp4boxMain /playground/gpac/applications/mp4box/main.c:5925
     #8 0x7ff19dc3ebf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
 
 previously allocated by thread T0 here:
     #0 0x7ff1a25fef30 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef30)
     #1 0x7ff1a0b32ab5 in mpgviddmx_process /playground/gpac/src/filters/reframe_mpgvid.c:584
     #2 0x7ff1a07e8920 in gf_filter_process_task /playground/gpac/src/filter_core/filter.c:2441
     #3 0x7ff1a07a8a62 in gf_fs_thread_proc /playground/gpac/src/filter_core/filter_session.c:1640
     #4 0x7ff1a07b3930 in gf_fs_run /playground/gpac/src/filter_core/filter_session.c:1877
     #5 0x7ff1a028bc15 in gf_media_import /playground/gpac/src/media_tools/media_import.c:1178
     #6 0x55dfd0ebb72f in convert_file_info /playground/gpac/applications/mp4box/fileimport.c:128
     #7 0x55dfd0e8e515 in mp4boxMain /playground/gpac/applications/mp4box/main.c:5925
     #8 0x7ff19dc3ebf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
 
 SUMMARY: AddressSanitizer: heap-use-after-free (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x79732) 
 Shadow bytes around the buggy address:
   0x0c4c7fffb5d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
   0x0c4c7fffb5e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
   0x0c4c7fffb5f0: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
   0x0c4c7fffb600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
   0x0c4c7fffb610: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
 =>0x0c4c7fffb620:[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
   0x0c4c7fffb630: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
   0x0c4c7fffb640: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
   0x0c4c7fffb650: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
   0x0c4c7fffb660: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
   0x0c4c7fffb670: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
 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
 ==9071==ABORTING

@aureliendavid
Copy link
Contributor

reposting my previous comment


hm this one is a bit trickier

when doing

if (ctx->hdr_store_alloc < ctx->hdr_store_size + pck_size - vosh_start) {
ctx->hdr_store_alloc = (u32) (ctx->hdr_store_size + pck_size - (u32) vosh_start);
ctx->hdr_store = gf_realloc(ctx->hdr_store, sizeof(char)*ctx->hdr_store_alloc);
}
memcpy(ctx->hdr_store + ctx->hdr_store_size, data + vosh_start, (size_t) (pck_size - vosh_start) );

the realloc() will (depending on conditions) free the old pointer before returning the new one

however, data might have been set to the old pointer value at

start = data = ctx->hdr_store;

so the memcpy() tries to copy from an already freed zone

I'm not sure about the best way to fix this yet but wanted to share the analysis

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