PR #25803 opened by AlexLaroche
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25803
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25803.patch
The check added to the skip opcode of decode_dds1() by d05f72c754
("dfa: improve boundary checks in decode_dds1()", CVE-2012-2798) has its
operands swapped: frame - frame_end is never positive, so it is smaller
than any skip whenever frame is before frame_end, and every DDS1 chunk
using a skip, even of zero pixels, is rejected as invalid data. Only a
zero skip at the very end of the frame passed.
Compare the skip against the space left in the frame, as the other
opcodes do. A skip past the end of the frame is still rejected.
None of the DFA samples in the FATE suite contains a DDS1 chunk, so the
FATE tests do not run this code.
To reproduce, this script writes a 16x16 DFA file with one DDS1 chunk made
of a 2x2 fill, a skip of 4 pixels and another fill:
```python
import struct
hdr = b'DFIA' + struct.pack('<HHHHI', 0, 1, 16, 16, 100)
hdr = hdr + struct.pack('<I', 0x80) + bytes(108)
pl = struct.pack('<HH', 3, 0x0008) + bytes([0x11, 0x22]) \
+ struct.pack('<H', 2) + bytes([0x33, 0x44])
open('skip.dfa', 'wb').write(hdr + b'DDS1' + struct.pack('<II', len(pl), 9)
+ pl + b'EOFR' + bytes(8))
```
Before: `ffmpeg -i skip.dfa -f framecrc -` fails with "Error decoding DDS1
chunk". After: the frame decodes. A skip past the end of the frame (0xffff
in place of 2) is still rejected. Tested with ASAN, and the 11 DFA FATE
samples decode as before. No FATE test is added as the suite has no DDS1
sample; I can provide one if wanted.
>From 535924e3d9c0a3a16b7d65d51491f4be082dd055 Mon Sep 17 00:00:00 2001
From: Alexandre Laroche <[email protected]>
Date: Fri, 6 Nov 2026 04:17:37 -0500
Subject: [PATCH] avcodec/dfa: fix the bounds check of DDS1 skips
The check added to the skip opcode of decode_dds1() by d05f72c754
("dfa: improve boundary checks in decode_dds1()", CVE-2012-2798) has its
operands swapped: frame - frame_end is never positive, so it is smaller
than any skip whenever frame is before frame_end, and every DDS1 chunk
using a skip, even of zero pixels, is rejected as invalid data. Only a
zero skip at the very end of the frame passed.
Compare the skip against the space left in the frame, as the other
opcodes do. A skip past the end of the frame is still rejected.
None of the DFA samples in the FATE suite contains a DDS1 chunk, so the
FATE tests do not run this code.
Signed-off-by: Alexandre Laroche <[email protected]>
---
libavcodec/dfa.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c
index 1efaefcb699..c099f22bdf5 100644
--- a/libavcodec/dfa.c
+++ b/libavcodec/dfa.c
@@ -175,7 +175,7 @@ static int decode_dds1(GetByteContext *gb, uint8_t *frame,
int width, int height
}
} else if (bitbuf & (mask << 1)) {
v = bytestream2_get_le16(gb)*2;
- if (frame - frame_end < v)
+ if (frame_end - frame < v)
return AVERROR_INVALIDDATA;
frame += v;
} else {
--
2.54.0
_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]