diff mbox

[FFmpeg-devel] avformat/mov: validate chunk_count vs stsc_data

Message ID 20190207225817.128142-1-chcunningham@chromium.org
State Accepted
Commit 1c15449ca9a5bfa387868ac55628397273da761f
Headers show

Commit Message

chcunningham@chromium.org Feb. 7, 2019, 10:58 p.m. UTC
Bad content may contain stsc boxes with a first_chunk index that
exceeds stco.entries (chunk_count). This ammends the existing check to
include cases where chunk_count == 0. It also patches up the case
when stsc refers to unknown chunks, but stts has no samples (so we
can simply ignore stsc).
---
 libavformat/mov.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

Comments

Michael Niedermayer Feb. 8, 2019, 10:51 a.m. UTC | #1
On Thu, Feb 07, 2019 at 02:58:17PM -0800, chcunningham wrote:
> Bad content may contain stsc boxes with a first_chunk index that
> exceeds stco.entries (chunk_count). This ammends the existing check to
> include cases where chunk_count == 0. It also patches up the case
> when stsc refers to unknown chunks, but stts has no samples (so we
> can simply ignore stsc).
> ---
>  libavformat/mov.c | 14 ++++++++++++--
>  1 file changed, 12 insertions(+), 2 deletions(-)

will apply

thanks

[...]
diff mbox

Patch

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 9b9739f788..45a40fe922 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -2694,8 +2694,11 @@  static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int in
 
     if (mov_stsc_index_valid(index, sc->stsc_count))
         chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
-    else
+    else {
+        // Validation for stsc / stco  happens earlier in mov_read_stsc + mov_read_trak.
+        av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
         chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
+    }
 
     return sc->stsc_data[index].count * (int64_t)chunk_count;
 }
@@ -4167,6 +4170,13 @@  static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 
     c->trak_index = -1;
 
+    // Here stsc refers to a chunk not described in stco. This is technically invalid,
+    // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
+    if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
+        sc->stsc_count = 0;
+        av_freep(&sc->stsc_data);
+    }
+
     /* sanity checks */
     if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
                             (!sc->sample_size && !sc->sample_count))) ||
@@ -4175,7 +4185,7 @@  static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
                st->index);
         return 0;
     }
-    if (sc->chunk_count && sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
+    if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
         av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
                st->index);
         return AVERROR_INVALIDDATA;