diff mbox series

[FFmpeg-devel] avformat/mov: abort reading truncated stts

Message ID 20211220195310.5633-1-ffmpeg@gyani.pro
State New
Headers show
Series [FFmpeg-devel] avformat/mov: abort reading truncated stts | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_ppc success Make finished
andriy/make_fate_ppc success Make fate finished

Commit Message

Gyan Doshi Dec. 20, 2021, 7:53 p.m. UTC
Avoids overreading the box and ingesting absurd values into stts_data
---

Fixes prolonged demuxing for fuzzer-generated files in the loop added in
patch for max_stts_delta

 libavformat/mov.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Andreas Rheinhardt Dec. 20, 2021, 7:57 p.m. UTC | #1
Gyan Doshi:
> Avoids overreading the box and ingesting absurd values into stts_data
> ---
> 
> Fixes prolonged demuxing for fuzzer-generated files in the loop added in
> patch for max_stts_delta
> 
>  libavformat/mov.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/libavformat/mov.c b/libavformat/mov.c
> index 2aed6e80ef..8d88119b29 100644
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -2935,6 +2935,11 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>      avio_rb24(pb); /* flags */
>      entries = avio_rb32(pb);
>  
> +    if (atom.size < 8 + entries*8) {

This can overflow.

> +        av_log(c->fc, AV_LOG_ERROR, "Truncated STTS box for st %d.\n", c->fc->nb_streams-1);
> +        return AVERROR_INVALIDDATA;
> +    }
> +
>      av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
>              c->fc->nb_streams-1, entries);
>  
>
Gyan Doshi Dec. 20, 2021, 8:36 p.m. UTC | #2
On 2021-12-21 01:27 am, Andreas Rheinhardt wrote:
> Gyan Doshi:
>> Avoids overreading the box and ingesting absurd values into stts_data
>> ---
>>
>> Fixes prolonged demuxing for fuzzer-generated files in the loop added in
>> patch for max_stts_delta
>>
>>   libavformat/mov.c | 5 +++++
>>   1 file changed, 5 insertions(+)
>>
>> diff --git a/libavformat/mov.c b/libavformat/mov.c
>> index 2aed6e80ef..8d88119b29 100644
>> --- a/libavformat/mov.c
>> +++ b/libavformat/mov.c
>> @@ -2935,6 +2935,11 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>>       avio_rb24(pb); /* flags */
>>       entries = avio_rb32(pb);
>>   
>> +    if (atom.size < 8 + entries*8) {
> This can overflow.

Can you illustrate?

atom.size is int64; entries is uint32.

And cppreference says,

"If the signed type can represent all values of the unsigned type, then 
the operand with the unsigned type is implicitly converted to the signed 
type. "

Gyan
Andreas Rheinhardt Dec. 20, 2021, 8:38 p.m. UTC | #3
Gyan Doshi:
> 
> 
> On 2021-12-21 01:27 am, Andreas Rheinhardt wrote:
>> Gyan Doshi:
>>> Avoids overreading the box and ingesting absurd values into stts_data
>>> ---
>>>
>>> Fixes prolonged demuxing for fuzzer-generated files in the loop added in
>>> patch for max_stts_delta
>>>
>>>   libavformat/mov.c | 5 +++++
>>>   1 file changed, 5 insertions(+)
>>>
>>> diff --git a/libavformat/mov.c b/libavformat/mov.c
>>> index 2aed6e80ef..8d88119b29 100644
>>> --- a/libavformat/mov.c
>>> +++ b/libavformat/mov.c
>>> @@ -2935,6 +2935,11 @@ static int mov_read_stts(MOVContext *c,
>>> AVIOContext *pb, MOVAtom atom)
>>>       avio_rb24(pb); /* flags */
>>>       entries = avio_rb32(pb);
>>>   +    if (atom.size < 8 + entries*8) {
>> This can overflow.
> 
> Can you illustrate?
> 
> atom.size is int64; entries is uint32.
> 
> And cppreference says,
> 
> "If the signed type can represent all values of the unsigned type, then
> the operand with the unsigned type is implicitly converted to the signed
> type. "
> 

8 + entries * 8 is calculated using unsigned with potential (defined)
wraparound; only afterwards is the result converted to int64_t
(presuming you have 32bit unsigned as usual) for the comparison.

- Andreas
diff mbox series

Patch

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 2aed6e80ef..8d88119b29 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -2935,6 +2935,11 @@  static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     avio_rb24(pb); /* flags */
     entries = avio_rb32(pb);
 
+    if (atom.size < 8 + entries*8) {
+        av_log(c->fc, AV_LOG_ERROR, "Truncated STTS box for st %d.\n", c->fc->nb_streams-1);
+        return AVERROR_INVALIDDATA;
+    }
+
     av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
             c->fc->nb_streams-1, entries);