PR #25006 opened by prasanna8585
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25006
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25006.patch

mov_read_iinf() reads each infe sub-box's declared size directly off the 
bitstream with no check against how much of the enclosing iinf box is actually 
left, unlike mov_read_iprp() which already bounds its ipco/ipma entries against 
the remaining iprp size (e3f5f17, 466ea98).

Track the same kind of running size budget here: subtract the 
version/flags/entry_count header from atom.size up front, then validate each 
infe_size against what is actually left before trusting it, mirroring e3f5f17's 
pattern exactly.

No memory-safety issue is known to depend on this; avio already bounds reads to 
the real file length. This is defense-in-depth, closing the same class of gap 
the sibling commits above just closed one box over.

Signed-off-by: Prasanna Dabi <[email protected]>

# Summary of changes

Briefly describe what this PR does and why. Bounds each `infe` entry's declared 
size against what's actually left in the enclosing `iinf` box, mirroring the 
same hardening pattern just applied to `ipco`/`ipma` in e3f5f17/466ea98. No 
crash is known to depend on this — it's defense-in-depth for the same bug class.

<!--
If this PR requires new FATE test samples, attach them to the PR and
list their target paths below (relative to the fate-suite root).

Attached filenames must match the sample's filename:

```fate-samples
# e.g. vorbis/new-sample.ogg
```
-->




From 6d7ab3ebfb4b81e6c47a8d8c207e000d62cec833 Mon Sep 17 00:00:00 2001
From: Prasanna Dabi <[email protected]>
Date: Sun, 11 Oct 2026 04:16:39 +0000
Subject: [PATCH] avformat/mov: bound infe entries by the iinf size

mov_read_iinf() reads each infe sub-box's declared size directly off
the bitstream with no check against how much of the enclosing iinf
box is actually left, unlike mov_read_iprp() which already bounds its
ipco/ipma entries against the remaining iprp size (e3f5f17, 466ea98).

Track the same kind of running size budget here: subtract the
version/flags/entry_count header from atom.size up front, then
validate each infe_size against what is actually left before trusting
it, mirroring e3f5f17's pattern exactly.

No memory-safety issue is known to depend on this; avio already bounds
reads to the real file length. This is defense-in-depth, closing the
same class of gap the sibling commits above just closed one box over.

Signed-off-by: Prasanna Dabi <[email protected]>
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01JMFTWfsNoeWv8CP3RFgDwT
---
 libavformat/mov.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index a7400aba06..7b3a06b6d9 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -9622,6 +9622,14 @@ static int mov_read_iinf(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
     if (entry_count > atom.size)
         return AVERROR_INVALIDDATA;
 
+    /* account for the version/flags/entry_count fields already consumed,
+     * so the per-entry loop below can bound each infe box by what is
+     * actually left in this iinf box, the same way mov_read_iprp() bounds
+     * ipco/ipma entries by the remaining iprp size. */
+    atom.size -= version ? 8 : 6;
+    if (atom.size < 0)
+        return AVERROR_INVALIDDATA;
+
     heif_item = av_realloc_array(c->heif_item, FFMAX(entry_count, 
c->nb_heif_item), sizeof(*c->heif_item));
     if (!heif_item)
         return AVERROR(ENOMEM);
@@ -9633,13 +9641,15 @@ static int mov_read_iinf(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 
     for (i = 0; i < entry_count; i++) {
         MOVAtom infe;
+        int64_t infe_size = avio_rb32(pb);
 
-        infe.size = avio_rb32(pb) - 8;
         infe.type = avio_rl32(pb);
-        if (avio_feof(pb)) {
+        if (avio_feof(pb) || infe_size < 8 || infe_size - 8 > atom.size) {
             ret = AVERROR_INVALIDDATA;
             goto fail;
         }
+        infe.size = infe_size - 8;
+        atom.size -= infe_size;
         ret = mov_read_infe(c, pb, infe);
         if (ret < 0)
             goto fail;
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to