diff mbox

[FFmpeg-devel,1/5] avcodec/binkaudio: Check sample rate

Message ID 20191010224011.5364-1-michael@niedermayer.cc
State Accepted
Commit 2fca09bce49c7de590560d9517fd2414b6c0c14f
Headers show

Commit Message

Michael Niedermayer Oct. 10, 2019, 10:40 p.m. UTC
Fixes: signed integer overflow: 1092624416 * 2 cannot be represented in type 'int'
Fixes: 18045/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_BINKAUDIO_RDFT_fuzzer-5718519492116480

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

Comments

Paul B Mahol Oct. 11, 2019, 8:55 a.m. UTC | #1
lgtm

On 10/11/19, Michael Niedermayer <michael@niedermayer.cc> wrote:
> Fixes: signed integer overflow: 1092624416 * 2 cannot be represented in type
> 'int'
> Fixes:
> 18045/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_BINKAUDIO_RDFT_fuzzer-5718519492116480
>
> Found-by: continuous fuzzing process
> https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> ---
>  libavcodec/binkaudio.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
> index 96cf968c66..2384ebf312 100644
> --- a/libavcodec/binkaudio.c
> +++ b/libavcodec/binkaudio.c
> @@ -95,6 +95,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
>      if (avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) {
>          // audio is already interleaved for the RDFT format variant
>          avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
> +        if (sample_rate > INT_MAX / avctx->channels)
> +            return AVERROR_INVALIDDATA;
>          sample_rate  *= avctx->channels;
>          s->channels = 1;
>          if (!s->version_b)
> --
> 2.23.0
>
> _______________________________________________
> 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".
Peter Ross Oct. 11, 2019, 9:51 a.m. UTC | #2
On Fri, Oct 11, 2019 at 12:40:07AM +0200, Michael Niedermayer wrote:
> Fixes: signed integer overflow: 1092624416 * 2 cannot be represented in type 'int'
> Fixes: 18045/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_BINKAUDIO_RDFT_fuzzer-5718519492116480
> 
> Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> ---
>  libavcodec/binkaudio.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
> index 96cf968c66..2384ebf312 100644
> --- a/libavcodec/binkaudio.c
> +++ b/libavcodec/binkaudio.c
> @@ -95,6 +95,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
>      if (avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) {
>          // audio is already interleaved for the RDFT format variant
>          avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
> +        if (sample_rate > INT_MAX / avctx->channels)
> +            return AVERROR_INVALIDDATA;
>          sample_rate  *= avctx->channels;
>          s->channels = 1;
>          if (!s->version_b)
> -- 
> 2.23.0

i think this checl belongs inside the fuzzer test harness, or as a general
purpose codec check.

the bink and smaker demuxers will only ever use BINKAUDIO_RDFT with 1 or 2 channels.

-- Peter
(A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B)
Michael Niedermayer Oct. 12, 2019, 8:47 p.m. UTC | #3
On Fri, Oct 11, 2019 at 08:51:54PM +1100, Peter Ross wrote:
> On Fri, Oct 11, 2019 at 12:40:07AM +0200, Michael Niedermayer wrote:
> > Fixes: signed integer overflow: 1092624416 * 2 cannot be represented in type 'int'
> > Fixes: 18045/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_BINKAUDIO_RDFT_fuzzer-5718519492116480
> > 
> > Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
> > Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> > ---
> >  libavcodec/binkaudio.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
> > index 96cf968c66..2384ebf312 100644
> > --- a/libavcodec/binkaudio.c
> > +++ b/libavcodec/binkaudio.c
> > @@ -95,6 +95,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
> >      if (avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) {
> >          // audio is already interleaved for the RDFT format variant
> >          avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
> > +        if (sample_rate > INT_MAX / avctx->channels)
> > +            return AVERROR_INVALIDDATA;
> >          sample_rate  *= avctx->channels;
> >          s->channels = 1;
> >          if (!s->version_b)
> > -- 
> > 2.23.0
> 
> i think this checl belongs inside the fuzzer test harness, or as a general
> purpose codec check.
> 
> the bink and smaker demuxers will only ever use BINKAUDIO_RDFT with 1 or 2 channels.

In the case of the overflow channels was 2

what check do you suggest to be done in general code ?
A check specific to the fuzzer would fail to prevent this from happening
outside the fuzzer

Thanks

[...]
James Almer Oct. 12, 2019, 9:53 p.m. UTC | #4
On 10/12/2019 5:47 PM, Michael Niedermayer wrote:
> On Fri, Oct 11, 2019 at 08:51:54PM +1100, Peter Ross wrote:
>> On Fri, Oct 11, 2019 at 12:40:07AM +0200, Michael Niedermayer wrote:
>>> Fixes: signed integer overflow: 1092624416 * 2 cannot be represented in type 'int'
>>> Fixes: 18045/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_BINKAUDIO_RDFT_fuzzer-5718519492116480
>>>
>>> Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
>>> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
>>> ---
>>>  libavcodec/binkaudio.c | 2 ++
>>>  1 file changed, 2 insertions(+)
>>>
>>> diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
>>> index 96cf968c66..2384ebf312 100644
>>> --- a/libavcodec/binkaudio.c
>>> +++ b/libavcodec/binkaudio.c
>>> @@ -95,6 +95,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
>>>      if (avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) {
>>>          // audio is already interleaved for the RDFT format variant
>>>          avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
>>> +        if (sample_rate > INT_MAX / avctx->channels)
>>> +            return AVERROR_INVALIDDATA;
>>>          sample_rate  *= avctx->channels;
>>>          s->channels = 1;
>>>          if (!s->version_b)
>>> -- 
>>> 2.23.0
>>
>> i think this checl belongs inside the fuzzer test harness, or as a general
>> purpose codec check.
>>
>> the bink and smaker demuxers will only ever use BINKAUDIO_RDFT with 1 or 2 channels.
> 
> In the case of the overflow channels was 2
> 
> what check do you suggest to be done in general code ?
> A check specific to the fuzzer would fail to prevent this from happening
> outside the fuzzer
> 
> Thanks

Judging by the bink demuxer reading 16 bits for sample_rate, I assume
binkaudio has a max valid value for it, like 44k or 48k, in which case a
check like the one for channels at the beginning of this function would
be the proper non general code fix. If not one of those two values, then
just <= UINT16_MAX.
Peter Ross Oct. 12, 2019, 11:51 p.m. UTC | #5
On Sat, Oct 12, 2019 at 06:53:05PM -0300, James Almer wrote:
> On 10/12/2019 5:47 PM, Michael Niedermayer wrote:
> > On Fri, Oct 11, 2019 at 08:51:54PM +1100, Peter Ross wrote:
> >> On Fri, Oct 11, 2019 at 12:40:07AM +0200, Michael Niedermayer wrote:
> >>> Fixes: signed integer overflow: 1092624416 * 2 cannot be represented in type 'int'
> >>> Fixes: 18045/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_BINKAUDIO_RDFT_fuzzer-5718519492116480
> >>>
> >>> Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
> >>> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> >>> ---
> >>>  libavcodec/binkaudio.c | 2 ++
> >>>  1 file changed, 2 insertions(+)
> >>>
> >>> diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
> >>> index 96cf968c66..2384ebf312 100644
> >>> --- a/libavcodec/binkaudio.c
> >>> +++ b/libavcodec/binkaudio.c
> >>> @@ -95,6 +95,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
> >>>      if (avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) {
> >>>          // audio is already interleaved for the RDFT format variant
> >>>          avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
> >>> +        if (sample_rate > INT_MAX / avctx->channels)
> >>> +            return AVERROR_INVALIDDATA;
> >>>          sample_rate  *= avctx->channels;
> >>>          s->channels = 1;
> >>>          if (!s->version_b)
> >>> -- 
> >>> 2.23.0
> >>
> >> i think this checl belongs inside the fuzzer test harness, or as a general
> >> purpose codec check.
> >>
> >> the bink and smaker demuxers will only ever use BINKAUDIO_RDFT with 1 or 2 channels.
> > 
> > In the case of the overflow channels was 2
> > 
> > what check do you suggest to be done in general code ?
> > A check specific to the fuzzer would fail to prevent this from happening
> > outside the fuzzer

fair enough, approve patch.

> Judging by the bink demuxer reading 16 bits for sample_rate, I assume
> binkaudio has a max valid value for it, like 44k or 48k, in which case a
> check like the one for channels at the beginning of this function would
> be the proper non general code fix. If not one of those two values, then
> just <= UINT16_MAX.

the bink demuxer supplied sample_reate is 16-bits wide, smacker is 24-bits.
the error can never happen when using ffmpeg+libavformat+libavcodec to play any
bink or smacker files, but i guess we need to account for other use cases.

-- Peter
(A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B)
Michael Niedermayer Oct. 14, 2019, 8:06 p.m. UTC | #6
On Sun, Oct 13, 2019 at 10:51:49AM +1100, Peter Ross wrote:
> On Sat, Oct 12, 2019 at 06:53:05PM -0300, James Almer wrote:
> > On 10/12/2019 5:47 PM, Michael Niedermayer wrote:
> > > On Fri, Oct 11, 2019 at 08:51:54PM +1100, Peter Ross wrote:
> > >> On Fri, Oct 11, 2019 at 12:40:07AM +0200, Michael Niedermayer wrote:
> > >>> Fixes: signed integer overflow: 1092624416 * 2 cannot be represented in type 'int'
> > >>> Fixes: 18045/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_BINKAUDIO_RDFT_fuzzer-5718519492116480
> > >>>
> > >>> Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
> > >>> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> > >>> ---
> > >>>  libavcodec/binkaudio.c | 2 ++
> > >>>  1 file changed, 2 insertions(+)
> > >>>
> > >>> diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
> > >>> index 96cf968c66..2384ebf312 100644
> > >>> --- a/libavcodec/binkaudio.c
> > >>> +++ b/libavcodec/binkaudio.c
> > >>> @@ -95,6 +95,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
> > >>>      if (avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) {
> > >>>          // audio is already interleaved for the RDFT format variant
> > >>>          avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
> > >>> +        if (sample_rate > INT_MAX / avctx->channels)
> > >>> +            return AVERROR_INVALIDDATA;
> > >>>          sample_rate  *= avctx->channels;
> > >>>          s->channels = 1;
> > >>>          if (!s->version_b)
> > >>> -- 
> > >>> 2.23.0
> > >>
> > >> i think this checl belongs inside the fuzzer test harness, or as a general
> > >> purpose codec check.
> > >>
> > >> the bink and smaker demuxers will only ever use BINKAUDIO_RDFT with 1 or 2 channels.
> > > 
> > > In the case of the overflow channels was 2
> > > 
> > > what check do you suggest to be done in general code ?
> > > A check specific to the fuzzer would fail to prevent this from happening
> > > outside the fuzzer
> 
> fair enough, approve patch.
> 
> > Judging by the bink demuxer reading 16 bits for sample_rate, I assume
> > binkaudio has a max valid value for it, like 44k or 48k, in which case a
> > check like the one for channels at the beginning of this function would
> > be the proper non general code fix. If not one of those two values, then
> > just <= UINT16_MAX.
> 
> the bink demuxer supplied sample_reate is 16-bits wide, smacker is 24-bits.
> the error can never happen when using ffmpeg+libavformat+libavcodec to play any
> bink or smacker files, but i guess we need to account for other use cases.

do you prefer the original patch or a check based on the maximum the current
demuxers can inject (24bits) ?

thx

[...]
Peter Ross Oct. 15, 2019, 9:44 a.m. UTC | #7
On Mon, Oct 14, 2019 at 10:06:55PM +0200, Michael Niedermayer wrote:
> On Sun, Oct 13, 2019 at 10:51:49AM +1100, Peter Ross wrote:
> > On Sat, Oct 12, 2019 at 06:53:05PM -0300, James Almer wrote:
> > > On 10/12/2019 5:47 PM, Michael Niedermayer wrote:
> > > > On Fri, Oct 11, 2019 at 08:51:54PM +1100, Peter Ross wrote:
> > > >> On Fri, Oct 11, 2019 at 12:40:07AM +0200, Michael Niedermayer wrote:
> > > >>> Fixes: signed integer overflow: 1092624416 * 2 cannot be represented in type 'int'
> > > >>> Fixes: 18045/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_BINKAUDIO_RDFT_fuzzer-5718519492116480
> > > >>>
> > > >>> Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
> > > >>> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> > > >>> ---
> > > >>>  libavcodec/binkaudio.c | 2 ++
> > > >>>  1 file changed, 2 insertions(+)
> > > >>>
> > > >>> diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
> > > >>> index 96cf968c66..2384ebf312 100644
> > > >>> --- a/libavcodec/binkaudio.c
> > > >>> +++ b/libavcodec/binkaudio.c
> > > >>> @@ -95,6 +95,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
> > > >>>      if (avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) {
> > > >>>          // audio is already interleaved for the RDFT format variant
> > > >>>          avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
> > > >>> +        if (sample_rate > INT_MAX / avctx->channels)
> > > >>> +            return AVERROR_INVALIDDATA;
> > > >>>          sample_rate  *= avctx->channels;
> > > >>>          s->channels = 1;
> > > >>>          if (!s->version_b)
> > > >>> -- 
> > > >>> 2.23.0
> > > >>
> > > >> i think this checl belongs inside the fuzzer test harness, or as a general
> > > >> purpose codec check.
> > > >>
> > > >> the bink and smaker demuxers will only ever use BINKAUDIO_RDFT with 1 or 2 channels.
> > > > 
> > > > In the case of the overflow channels was 2
> > > > 
> > > > what check do you suggest to be done in general code ?
> > > > A check specific to the fuzzer would fail to prevent this from happening
> > > > outside the fuzzer
> > 
> > fair enough, approve patch.
> > 
> > > Judging by the bink demuxer reading 16 bits for sample_rate, I assume
> > > binkaudio has a max valid value for it, like 44k or 48k, in which case a
> > > check like the one for channels at the beginning of this function would
> > > be the proper non general code fix. If not one of those two values, then
> > > just <= UINT16_MAX.
> > 
> > the bink demuxer supplied sample_reate is 16-bits wide, smacker is 24-bits.
> > the error can never happen when using ffmpeg+libavformat+libavcodec to play any
> > bink or smacker files, but i guess we need to account for other use cases.
> 
> do you prefer the original patch or a check based on the maximum the current
> demuxers can inject (24bits) ?

original one is good.

-- Peter
(A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B)
Michael Niedermayer Oct. 16, 2019, 5:54 p.m. UTC | #8
On Tue, Oct 15, 2019 at 08:44:23PM +1100, Peter Ross wrote:
> On Mon, Oct 14, 2019 at 10:06:55PM +0200, Michael Niedermayer wrote:
> > On Sun, Oct 13, 2019 at 10:51:49AM +1100, Peter Ross wrote:
> > > On Sat, Oct 12, 2019 at 06:53:05PM -0300, James Almer wrote:
> > > > On 10/12/2019 5:47 PM, Michael Niedermayer wrote:
> > > > > On Fri, Oct 11, 2019 at 08:51:54PM +1100, Peter Ross wrote:
> > > > >> On Fri, Oct 11, 2019 at 12:40:07AM +0200, Michael Niedermayer wrote:
> > > > >>> Fixes: signed integer overflow: 1092624416 * 2 cannot be represented in type 'int'
> > > > >>> Fixes: 18045/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_BINKAUDIO_RDFT_fuzzer-5718519492116480
> > > > >>>
> > > > >>> Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
> > > > >>> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> > > > >>> ---
> > > > >>>  libavcodec/binkaudio.c | 2 ++
> > > > >>>  1 file changed, 2 insertions(+)
> > > > >>>
> > > > >>> diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
> > > > >>> index 96cf968c66..2384ebf312 100644
> > > > >>> --- a/libavcodec/binkaudio.c
> > > > >>> +++ b/libavcodec/binkaudio.c
> > > > >>> @@ -95,6 +95,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
> > > > >>>      if (avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) {
> > > > >>>          // audio is already interleaved for the RDFT format variant
> > > > >>>          avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
> > > > >>> +        if (sample_rate > INT_MAX / avctx->channels)
> > > > >>> +            return AVERROR_INVALIDDATA;
> > > > >>>          sample_rate  *= avctx->channels;
> > > > >>>          s->channels = 1;
> > > > >>>          if (!s->version_b)
> > > > >>> -- 
> > > > >>> 2.23.0
> > > > >>
> > > > >> i think this checl belongs inside the fuzzer test harness, or as a general
> > > > >> purpose codec check.
> > > > >>
> > > > >> the bink and smaker demuxers will only ever use BINKAUDIO_RDFT with 1 or 2 channels.
> > > > > 
> > > > > In the case of the overflow channels was 2
> > > > > 
> > > > > what check do you suggest to be done in general code ?
> > > > > A check specific to the fuzzer would fail to prevent this from happening
> > > > > outside the fuzzer
> > > 
> > > fair enough, approve patch.
> > > 
> > > > Judging by the bink demuxer reading 16 bits for sample_rate, I assume
> > > > binkaudio has a max valid value for it, like 44k or 48k, in which case a
> > > > check like the one for channels at the beginning of this function would
> > > > be the proper non general code fix. If not one of those two values, then
> > > > just <= UINT16_MAX.
> > > 
> > > the bink demuxer supplied sample_reate is 16-bits wide, smacker is 24-bits.
> > > the error can never happen when using ffmpeg+libavformat+libavcodec to play any
> > > bink or smacker files, but i guess we need to account for other use cases.
> > 
> > do you prefer the original patch or a check based on the maximum the current
> > demuxers can inject (24bits) ?
> 
> original one is good.

ok will apply that

thanks

[...]
diff mbox

Patch

diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
index 96cf968c66..2384ebf312 100644
--- a/libavcodec/binkaudio.c
+++ b/libavcodec/binkaudio.c
@@ -95,6 +95,8 @@  static av_cold int decode_init(AVCodecContext *avctx)
     if (avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) {
         // audio is already interleaved for the RDFT format variant
         avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+        if (sample_rate > INT_MAX / avctx->channels)
+            return AVERROR_INVALIDDATA;
         sample_rate  *= avctx->channels;
         s->channels = 1;
         if (!s->version_b)