diff mbox

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

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

Commit Message

Michael Niedermayer Sept. 3, 2019, 12:14 a.m. UTC
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. UTC | #1
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. UTC | #2
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. UTC | #3
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".
>
Michael Niedermayer Sept. 25, 2019, 3:18 p.m. UTC | #4
On Tue, Sep 03, 2019 at 02:39:27PM -0300, James Almer wrote:
> 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.

ill apply a patch which does the check in ff_get_buffer() at the same
point where its done for max_pixels

thx

[...]
Michael Niedermayer Sept. 28, 2019, 4:32 p.m. UTC | #5
On Tue, Sep 03, 2019 at 02:39:27PM -0300, James Almer wrote:
> 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.

will apply with these changes and some more to reset the incorrect samples in
case of ff_get_buffer failure

thx

[...]
diff mbox

Patch

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");