diff mbox series

[FFmpeg-devel] avformat/asfdec_o: limit recursion depth in asf_read_unknown()

Message ID 20220830233112.24688-1-michael@niedermayer.cc
State Accepted
Commit 1f1a368169ef9d945dc4b4764f5c60ba9bbc9134
Headers show
Series [FFmpeg-devel] avformat/asfdec_o: limit recursion depth in asf_read_unknown() | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Michael Niedermayer Aug. 30, 2022, 11:31 p.m. UTC
The threshold of 5 is arbitrary, both smaller and larger should work fine

Fixes: Stack overflow
Fixes: 50603/clusterfuzz-testcase-minimized-ffmpeg_dem_ASF_O_fuzzer-6049302564175872

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
 libavformat/asfdec_o.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

Comments

Michael Niedermayer Aug. 31, 2022, 9:45 a.m. UTC | #1
On Wed, Aug 31, 2022 at 01:31:12AM +0200, Michael Niedermayer wrote:
> The threshold of 5 is arbitrary, both smaller and larger should work fine
> 
> Fixes: Stack overflow
> Fixes: 50603/clusterfuzz-testcase-minimized-ffmpeg_dem_ASF_O_fuzzer-6049302564175872
> 
> Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> ---
>  libavformat/asfdec_o.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)

i will apply and backport this soon so its in 5.1.1

[...]
diff mbox series

Patch

diff --git a/libavformat/asfdec_o.c b/libavformat/asfdec_o.c
index 907be6de04f..48b7d17322d 100644
--- a/libavformat/asfdec_o.c
+++ b/libavformat/asfdec_o.c
@@ -109,6 +109,7 @@  typedef struct ASFContext {
     int64_t data_offset;
     int64_t first_packet_offset; // packet offset
     int64_t unknown_offset;   // for top level header objects or subobjects without specified behavior
+    int in_asf_read_unknown;
 
     // ASF file must not contain more than 128 streams according to the specification
     ASFStream *asf_st[ASF_MAX_STREAMS];
@@ -173,7 +174,7 @@  static int asf_read_unknown(AVFormatContext *s, const GUIDParseTable *g)
     uint64_t size   = avio_rl64(pb);
     int ret;
 
-    if (size > INT64_MAX)
+    if (size > INT64_MAX || asf->in_asf_read_unknown > 5)
         return AVERROR_INVALIDDATA;
 
     if (asf->is_header)
@@ -182,8 +183,11 @@  static int asf_read_unknown(AVFormatContext *s, const GUIDParseTable *g)
     if (!g->is_subobject) {
         if (!(ret = strcmp(g->name, "Header Extension")))
             avio_skip(pb, 22); // skip reserved fields and Data Size
-        if ((ret = detect_unknown_subobject(s, asf->unknown_offset,
-                                            asf->unknown_size)) < 0)
+        asf->in_asf_read_unknown ++;
+        ret = detect_unknown_subobject(s, asf->unknown_offset,
+                                            asf->unknown_size);
+        asf->in_asf_read_unknown --;
+        if (ret < 0)
             return ret;
     } else {
         if (size < 24) {