Coordinated Disclosure Timeline
- 2024-09-26: Issue reported at https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3851
- 2024-09-26: Issue acknowledged
- 2024-12-03: Fixed and disclosed
Project
Gstreamer
Tested Version
1.25.0.1
Details
Integer underflow in qtdemux_parse_theora_extension leading to function pointer overwrite (GHSL-2024-166
)
An integer underflow has been detected in the function qtdemux_parse_theora_extension within qtdemux.c
.
The vulnerability occurs due to an underflow of the gint size
variable, which causes size
to hold a large unintended value when cast to an unsigned integer:
static gboolean qtdemux_parse_theora_extension (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * xdxt){
...
gint size;
...
size -= 8; //Size value = -7 => 0xfffffff9 (unsigned)
...
}
This 32-bit negative value is then cast to a 64-bit unsigned integer (0xfffffffffffffffa) in a subsequent call to gst_buffer_new_and_alloc:
buffer = gst_buffer_new_and_alloc (size);
gst_buffer_fill (buffer, 0, buf, size);
stream->buffers = g_slist_append (stream->buffers, buffer);
The function gst_buffer_new_allocate then attempts to allocate memory, eventually calling _sysmem_new_block
.
The function _sysmem_new_block adds alignment and header size to the (unsigned) size, causing the overflow of the ‘slice_size’ variable. As a result, only 0x89 bytes are allocated, despite the large input size:
static GstMemorySystem *_sysmem_new_block (GstMemoryFlags flags, gsize maxsize, gsize align, gsize offset, gsize size){
...
/* ensure configured alignment */
align |= gst_memory_alignment;
/* allocate more to compensate for alignment */
maxsize += align;
/* alloc header and data in one block */
slice_size = sizeof (GstMemorySystem) + maxsize; => 0x89!!!!
mem = g_malloc (slice_size);
...
When the following memcpy
call occurs in gst_buffer_fill, the data from the input file will overwrite the content of the GstMapInfo info
structure:
gsize gst_buffer_fill (GstBuffer * buffer, gsize offset, gconstpointer src, gsize size){
...
memcpy ((guint8 *) info.data + offset, ptr, tocopy);
...
}
Finally, during the call to gst_memory_unmap, the overwritten memory may cause a function pointer hijack, as the mem->allocator->mem_unmap_full
function is called with a corrupted pointer:
void gst_memory_unmap (GstMemory * mem, GstMapInfo * info){
...
if (mem->allocator->mem_unmap_full)
mem->allocator->mem_unmap_full (mem, info);
else
mem->allocator->mem_unmap (mem);
...
}
This function pointer overwrite could allow an attacker to alter the execution flow of the program, leading to arbitrary code execution.
Impact
This vulnerability could allow an attacker to hijack the execution flow, potentially leading to code execution.
CVE
- CVE-2024-47606
Credit
This issue was discovered and reported by GHSL team member @antonio-morales (Antonio Morales).
Contact
You can contact the GHSL team at securitylab@github.com
, please include a reference to GHSL-2024-166
in any communication regarding this issue.