Heap buffer overflow in gst_uri_construct
Hi. I'm a security researcher.
I found a bug in gst_uri_construct function which is is deprecated, but still available.
I checked only on ubuntu:
info
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.4 LTS (Focal Fossa)"
$ cat /usr/include/gstreamer-1.0/gst/gsturi.h | grep gst_uri_construct
gchar * gst_uri_construct (const gchar * protocol,
gstreamer
version is 1.19.2
.
Static analyze details:
/root/.conan/data/gstreamer/1.19.2/_/_/build/73b8e5764d1ecac9e3307d9fab8efcdb2c7b3e51/source_subfolder/gst/gsturi.c:238:12: Dereference of null pointer [core.NullDereference]
*q++ = HEX_ESCAPE; /* means hex coming */
^
Steps:
1, gsturi.c:516:3: Assuming 'location' is not equal to null
2, gsturi.c:519:13: Calling 'escape_string_internal'
3, gsturi.c:194:1: Entered call from 'gst_uri_construct'
4, gsturi.c:218:20: Assuming the condition is true
5, gsturi.c:218:20: Entering loop body
6, gsturi.c:220:10: Assuming 'c' is < 32
7, gsturi.c:218:3: Looping back to the head of the loop
8, gsturi.c:218:20: Assuming the condition is false
9, gsturi.c:234:32: Entering loop body
10, gsturi.c:238:8: Null pointer value stored to 'q'
11, gsturi.c:238:12: Dereference of null pointer
Dynamic analyze details:
#include <gst/gsturi.h>
#include <stdint.h>
#include <stddef.h>
#include <string>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size == 0){
return 0;
}
gchar * uri = gst_uri_construct("file", (const char*)data);
if (uri != NULL){
g_free(uri);
}
return 0;
}
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 3667446100
INFO: Loaded 1 modules (4 inline 8-bit counters): 4 [0x564be5b961b8, 0x564be5b961bc),
INFO: Loaded 1 PC tables (4 PCs): 4 [0x564be5b961c0,0x564be5b96200),
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
=================================================================
==98802==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000d51 at pc 0x564be53d22f8 bp 0x7fffb0fd0a20 sp 0x7fffb0fd0a18
READ of size 1 at 0x602000000d51 thread T0
#0 0x564be53d22f7 in escape_string_internal /root/.conan/data/gstreamer/1.19.2/_/_/build/9fdd02815ee09896fb049394155812d1fbeaef93/build_subfolder/../source_subfolder/gst/gsturi.c:218:20
#1 0x564be53d21ad in gst_uri_construct /root/.conan/data/gstreamer/1.19.2/_/_/build/9fdd02815ee09896fb049394155812d1fbeaef93/build_subfolder/../source_subfolder/gst/gsturi.c:519:13
#2 0x564be53d10f0 in LLVMFuzzerTestOneInput (/test_app+0x2c20f0) (BuildId: eef4588824956bd87950ac3a715edc070a3dab0d)
#3 0x564be52f8222 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/test_app+0x1e9222) (BuildId: eef4588824956bd87950ac3a715edc070a3dab0d)
#4 0x564be52f7979 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) (/test_app+0x1e8979) (BuildId: eef4588824956bd87950ac3a715edc070a3dab0d)
#5 0x564be52f9656 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile> >&) (/test_app+0x1ea656) (BuildId: eef4588824956bd87950ac3a715edc070a3dab0d)
#6 0x564be52f9ac2 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile> >&) (/test_app+0x1eaac2) (BuildId: eef4588824956bd87950ac3a715edc070a3dab0d)
#7 0x564be52e85c2 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/test_app+0x1d95c2) (BuildId: eef4588824956bd87950ac3a715edc070a3dab0d)
#8 0x564be5311152 in main (/test_app+0x202152) (BuildId: eef4588824956bd87950ac3a715edc070a3dab0d)
#9 0x7fe98b76f0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2) (BuildId: 9fdb74e7b217d06c93172a8243f8547f947ee6d1)
#10 0x564be52dd10d in _start (/test_app+0x1ce10d) (BuildId: eef4588824956bd87950ac3a715edc070a3dab0d)
0x602000000d51 is located 0 bytes to the right of 1-byte region [0x602000000d50,0x602000000d51)
allocated by thread T0 here:
#0 0x564be53cebad in operator new[](unsigned long) (/test_app+0x2bfbad) (BuildId: eef4588824956bd87950ac3a715edc070a3dab0d)
#1 0x564be52f8131 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/test_app+0x1e9131) (BuildId: eef4588824956bd87950ac3a715edc070a3dab0d)
#2 0x564be52f7979 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) (/test_app+0x1e8979) (BuildId: eef4588824956bd87950ac3a715edc070a3dab0d)
#3 0x564be52f9656 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile> >&) (/test_app+0x1ea656) (BuildId: eef4588824956bd87950ac3a715edc070a3dab0d)
#4 0x564be52f9ac2 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile> >&) (/test_app+0x1eaac2) (BuildId: eef4588824956bd87950ac3a715edc070a3dab0d)
#5 0x564be52e85c2 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/test_app+0x1d95c2) (BuildId: eef4588824956bd87950ac3a715edc070a3dab0d)
#6 0x564be5311152 in main (/test_app+0x202152) (BuildId: eef4588824956bd87950ac3a715edc070a3dab0d)
#7 0x7fe98b76f0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2) (BuildId: 9fdb74e7b217d06c93172a8243f8547f947ee6d1)
SUMMARY: AddressSanitizer: heap-buffer-overflow /root/.conan/data/gstreamer/1.19.2/_/_/build/9fdd02815ee09896fb049394155812d1fbeaef93/build_subfolder/../source_subfolder/gst/gsturi.c:218:20 in escape_string_internal
Shadow bytes around the buggy address:
0x0c047fff8150: fa fa 00 00 fa fa 00 00 fa fa 00 fa fa fa 00 00
0x0c047fff8160: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00
0x0c047fff8170: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 fa
0x0c047fff8180: fa fa 00 00 fa fa 00 00 fa fa 00 fa fa fa 00 00
0x0c047fff8190: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 fa
=>0x0c047fff81a0: fa fa fd fa fa fa 01 fa fa fa[01]fa fa fa 05 fa
0x0c047fff81b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff81c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff81d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff81e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff81f0: 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
==98802==ABORTING
MS: 0 ; base unit: 0000000000000000000000000000000000000000
0xa,
\012
artifact_prefix='./'; Test unit written to ./crash-adc83b19e793491b1c6ea0fd8b46cd9f32e592fc
Base64: Cg==