[FFmpeg-devel,5/5] avcodec/apedec: Check max_samples

Submitted by Michael Niedermayer on Sept. 3, 2019, 12:14 a.m.

Details

Message ID 20190903001426.8957-5-michael@niedermayer.cc
State New
Headers show

Commit Message

Michael Niedermayer Sept. 3, 2019, 12:14 a.m.
Fixes: OOM
Fixes: 16627/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_APE_fuzzer-5638059583864832

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

Comments

James Almer Sept. 3, 2019, 12:40 a.m.
On 9/2/2019 9:14 PM, Michael Niedermayer wrote:
> Fixes: OOM
> Fixes: 16627/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_APE_fuzzer-5638059583864832
> 
> Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> ---
>  libavcodec/apedec.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
> index e218f7c043..774ce18531 100644
> --- a/libavcodec/apedec.c
> +++ b/libavcodec/apedec.c
> @@ -1475,6 +1475,9 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
>              return AVERROR_INVALIDDATA;
>          }
>  
> +        if (nblocks * (int64_t)avctx->channels > avctx->max_samples)
> +            return AVERROR(EINVAL);
> +

Shouldn't this be checked in ff_get_buffer()? Same as max_pixels, but
checking "frame->nb_samples > avctx->max_samples" instead or
width/height. Otherwise it will barely be used.

>          /* Initialize the frame decoder */
>          if (init_frame_decoder(s) < 0) {
>              av_log(avctx, AV_LOG_ERROR, "Error reading frame header\n");
>
Michael Niedermayer Sept. 3, 2019, 11:13 a.m.
On Mon, Sep 02, 2019 at 09:40:47PM -0300, James Almer wrote:
> On 9/2/2019 9:14 PM, Michael Niedermayer wrote:
> > Fixes: OOM
> > Fixes: 16627/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_APE_fuzzer-5638059583864832
> > 
> > Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
> > Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> > ---
> >  libavcodec/apedec.c | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
> > index e218f7c043..774ce18531 100644
> > --- a/libavcodec/apedec.c
> > +++ b/libavcodec/apedec.c
> > @@ -1475,6 +1475,9 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
> >              return AVERROR_INVALIDDATA;
> >          }
> >  
> > +        if (nblocks * (int64_t)avctx->channels > avctx->max_samples)
> > +            return AVERROR(EINVAL);
> > +
> 
> Shouldn't this be checked in ff_get_buffer()? Same as max_pixels, but
> checking "frame->nb_samples > avctx->max_samples" instead or
> width/height. Otherwise it will barely be used.

you are correct, it should be checked in *get_buffer somewhere too.
But the offending allocation occurs before any *get_buffer calls so
this check here is what is neccessary and sufficient for this specific
bug

Thanks

[...]
James Almer Sept. 3, 2019, 5:39 p.m.
On 9/3/2019 8:13 AM, Michael Niedermayer wrote:
> On Mon, Sep 02, 2019 at 09:40:47PM -0300, James Almer wrote:
>> On 9/2/2019 9:14 PM, Michael Niedermayer wrote:
>>> Fixes: OOM
>>> Fixes: 16627/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_APE_fuzzer-5638059583864832
>>>
>>> Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
>>> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
>>> ---
>>>  libavcodec/apedec.c | 3 +++
>>>  1 file changed, 3 insertions(+)
>>>
>>> diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
>>> index e218f7c043..774ce18531 100644
>>> --- a/libavcodec/apedec.c
>>> +++ b/libavcodec/apedec.c
>>> @@ -1475,6 +1475,9 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
>>>              return AVERROR_INVALIDDATA;
>>>          }
>>>  
>>> +        if (nblocks * (int64_t)avctx->channels > avctx->max_samples)
>>> +            return AVERROR(EINVAL);
>>> +
>>
>> Shouldn't this be checked in ff_get_buffer()? Same as max_pixels, but
>> checking "frame->nb_samples > avctx->max_samples" instead or
>> width/height. Otherwise it will barely be used.
> 
> you are correct, it should be checked in *get_buffer somewhere too.
> But the offending allocation occurs before any *get_buffer calls so
> this check here is what is neccessary and sufficient for this specific
> bug

If the allocation you're talking about is
https://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavcodec/apedec.c;h=490b11b94e0b1666f18248b2b247c874fed6e0bc;hb=HEAD#l1500
then you could just move it (and the five lines that follow it) right
below the ff_get_buffer() call.

But it should be ok either way.

> 
> Thanks
> 
> [...]
> 
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>

Patch hide | download patch | download mbox

diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
index e218f7c043..774ce18531 100644
--- a/libavcodec/apedec.c
+++ b/libavcodec/apedec.c
@@ -1475,6 +1475,9 @@  static int ape_decode_frame(AVCodecContext *avctx, void *data,
             return AVERROR_INVALIDDATA;
         }
 
+        if (nblocks * (int64_t)avctx->channels > avctx->max_samples)
+            return AVERROR(EINVAL);
+
         /* Initialize the frame decoder */
         if (init_frame_decoder(s) < 0) {
             av_log(avctx, AV_LOG_ERROR, "Error reading frame header\n");