diff mbox series

[FFmpeg-devel] avcodec/ff_mpv_encode_end: fix a crash for null s->avctx

Message ID 20200825093541.38010-1-guangxin.xu@intel.com
State Superseded
Headers show
Series [FFmpeg-devel] avcodec/ff_mpv_encode_end: fix a crash for null s->avctx | expand

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Xu, Guangxin Aug. 25, 2020, 9:35 a.m. UTC
Steps to reproduce:
1. ./configure --enable-debug=3 --disable-libx264 && make install
2. ffmpeg -i input.mp4 -profile:v baseline output.mp4 -y

you will see a crash like this:
[mpeg4 @ 0x5555575854c0] [Eval @ 0x7fffffffbf80] Undefined constant or missing '(' in 'baseline'
[mpeg4 @ 0x5555575854c0] Unable to parse option value "baseline"
[mpeg4 @ 0x5555575854c0] Error setting option profile to value baseline.
Thread 1 "ffmpeg" received signal SIGSEGV, Segmentation fault.

root cause:
If the codec has FF_CODEC_CAP_INIT_CLEANUP flag, and avcodec_open2 got an error before avctx->codec->init,
the ff_mpv_encode_end will face a null s->avctx.
---
 libavcodec/mpegvideo_enc.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

Comments

James Almer Aug. 25, 2020, 2:37 p.m. UTC | #1
On 8/25/2020 6:35 AM, Xu Guangxin wrote:
> Steps to reproduce:
> 1. ./configure --enable-debug=3 --disable-libx264 && make install
> 2. ffmpeg -i input.mp4 -profile:v baseline output.mp4 -y
> 
> you will see a crash like this:
> [mpeg4 @ 0x5555575854c0] [Eval @ 0x7fffffffbf80] Undefined constant or missing '(' in 'baseline'
> [mpeg4 @ 0x5555575854c0] Unable to parse option value "baseline"
> [mpeg4 @ 0x5555575854c0] Error setting option profile to value baseline.
> Thread 1 "ffmpeg" received signal SIGSEGV, Segmentation fault.
> 
> root cause:
> If the codec has FF_CODEC_CAP_INIT_CLEANUP flag, and avcodec_open2 got an error before avctx->codec->init,
> the ff_mpv_encode_end will face a null s->avctx.
> ---
>  libavcodec/mpegvideo_enc.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
> index 09697d89c8..a79309d1b9 100644
> --- a/libavcodec/mpegvideo_enc.c
> +++ b/libavcodec/mpegvideo_enc.c
> @@ -1078,9 +1078,10 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
>          av_frame_free(&s->tmp_frames[i]);
>  
>      ff_free_picture_tables(&s->new_picture);
> -    ff_mpeg_unref_picture(s->avctx, &s->new_picture);
> -
> -    av_freep(&s->avctx->stats_out);
> +    if (s->avctx) {

Judging by the av_freep(&avctx->extradata) call earlier in the function
i assume s->avctx is meant to be the same as avctx, which is guaranteed
to not be NULL, so you can use that instead.

> +        ff_mpeg_unref_picture(s->avctx, &s->new_picture);
> +        av_freep(&s->avctx->stats_out);
> +    }
>      av_freep(&s->ac_stats);
>  
>      if(s->q_chroma_intra_matrix   != s->q_intra_matrix  ) av_freep(&s->q_chroma_intra_matrix);
>
Guangxin Xu Aug. 25, 2020, 3:08 p.m. UTC | #2
Hi James,
thanks for the review.
We can't assume s->avctx == avctx. in
https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/smvjpegdec.c, it
will be assigned to a new allocated codec context.
Currently, it's no mpeg video encoder doing this, but in the future, some
subclass maybe.

On Tue, Aug 25, 2020 at 10:38 PM James Almer <jamrial@gmail.com> wrote:

> On 8/25/2020 6:35 AM, Xu Guangxin wrote:
> > Steps to reproduce:
> > 1. ./configure --enable-debug=3 --disable-libx264 && make install
> > 2. ffmpeg -i input.mp4 -profile:v baseline output.mp4 -y
> >
> > you will see a crash like this:
> > [mpeg4 @ 0x5555575854c0] [Eval @ 0x7fffffffbf80] Undefined constant or
> missing '(' in 'baseline'
> > [mpeg4 @ 0x5555575854c0] Unable to parse option value "baseline"
> > [mpeg4 @ 0x5555575854c0] Error setting option profile to value baseline.
> > Thread 1 "ffmpeg" received signal SIGSEGV, Segmentation fault.
> >
> > root cause:
> > If the codec has FF_CODEC_CAP_INIT_CLEANUP flag, and avcodec_open2 got
> an error before avctx->codec->init,
> > the ff_mpv_encode_end will face a null s->avctx.
> > ---
> >  libavcodec/mpegvideo_enc.c | 7 ++++---
> >  1 file changed, 4 insertions(+), 3 deletions(-)
> >
> > diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
> > index 09697d89c8..a79309d1b9 100644
> > --- a/libavcodec/mpegvideo_enc.c
> > +++ b/libavcodec/mpegvideo_enc.c
> > @@ -1078,9 +1078,10 @@ av_cold int ff_mpv_encode_end(AVCodecContext
> *avctx)
> >          av_frame_free(&s->tmp_frames[i]);
> >
> >      ff_free_picture_tables(&s->new_picture);
> > -    ff_mpeg_unref_picture(s->avctx, &s->new_picture);
> > -
> > -    av_freep(&s->avctx->stats_out);
> > +    if (s->avctx) {
>
> Judging by the av_freep(&avctx->extradata) call earlier in the function
> i assume s->avctx is meant to be the same as avctx, which is guaranteed
> to not be NULL, so you can use that instead.
>
> > +        ff_mpeg_unref_picture(s->avctx, &s->new_picture);
> > +        av_freep(&s->avctx->stats_out);
> > +    }
> >      av_freep(&s->ac_stats);
> >
> >      if(s->q_chroma_intra_matrix   != s->q_intra_matrix  )
> av_freep(&s->q_chroma_intra_matrix);
> >
>
> _______________________________________________
> 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".
James Almer Aug. 25, 2020, 3:52 p.m. UTC | #3
On 8/25/2020 12:08 PM, Guangxin Xu wrote:
> Hi James,
> thanks for the review.
> We can't assume s->avctx == avctx. in
> https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/smvjpegdec.c, it
> will be assigned to a new allocated codec context.
> Currently, it's no mpeg video encoder doing this, but in the future, some
> subclass maybe.

I was talking specifically about MpegEncContext, yes. I don't think that
will change at all, but i have no strong opinion about it anyway, so
your patch LGTM.

> 
> On Tue, Aug 25, 2020 at 10:38 PM James Almer <jamrial@gmail.com> wrote:
> 
>> On 8/25/2020 6:35 AM, Xu Guangxin wrote:
>>> Steps to reproduce:
>>> 1. ./configure --enable-debug=3 --disable-libx264 && make install
>>> 2. ffmpeg -i input.mp4 -profile:v baseline output.mp4 -y
>>>
>>> you will see a crash like this:
>>> [mpeg4 @ 0x5555575854c0] [Eval @ 0x7fffffffbf80] Undefined constant or
>> missing '(' in 'baseline'
>>> [mpeg4 @ 0x5555575854c0] Unable to parse option value "baseline"
>>> [mpeg4 @ 0x5555575854c0] Error setting option profile to value baseline.
>>> Thread 1 "ffmpeg" received signal SIGSEGV, Segmentation fault.
>>>
>>> root cause:
>>> If the codec has FF_CODEC_CAP_INIT_CLEANUP flag, and avcodec_open2 got
>> an error before avctx->codec->init,
>>> the ff_mpv_encode_end will face a null s->avctx.
>>> ---
>>>  libavcodec/mpegvideo_enc.c | 7 ++++---
>>>  1 file changed, 4 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
>>> index 09697d89c8..a79309d1b9 100644
>>> --- a/libavcodec/mpegvideo_enc.c
>>> +++ b/libavcodec/mpegvideo_enc.c
>>> @@ -1078,9 +1078,10 @@ av_cold int ff_mpv_encode_end(AVCodecContext
>> *avctx)
>>>          av_frame_free(&s->tmp_frames[i]);
>>>
>>>      ff_free_picture_tables(&s->new_picture);
>>> -    ff_mpeg_unref_picture(s->avctx, &s->new_picture);
>>> -
>>> -    av_freep(&s->avctx->stats_out);
>>> +    if (s->avctx) {
>>
>> Judging by the av_freep(&avctx->extradata) call earlier in the function
>> i assume s->avctx is meant to be the same as avctx, which is guaranteed
>> to not be NULL, so you can use that instead.
>>
>>> +        ff_mpeg_unref_picture(s->avctx, &s->new_picture);
>>> +        av_freep(&s->avctx->stats_out);
>>> +    }
>>>      av_freep(&s->ac_stats);
>>>
>>>      if(s->q_chroma_intra_matrix   != s->q_intra_matrix  )
>> av_freep(&s->q_chroma_intra_matrix);
>>>
>>
>> _______________________________________________
>> 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".
> _______________________________________________
> 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 Aug. 25, 2020, 9:50 p.m. UTC | #4
On Tue, Aug 25, 2020 at 11:37:59AM -0300, James Almer wrote:
> On 8/25/2020 6:35 AM, Xu Guangxin wrote:
> > Steps to reproduce:
> > 1. ./configure --enable-debug=3 --disable-libx264 && make install
> > 2. ffmpeg -i input.mp4 -profile:v baseline output.mp4 -y
> > 
> > you will see a crash like this:
> > [mpeg4 @ 0x5555575854c0] [Eval @ 0x7fffffffbf80] Undefined constant or missing '(' in 'baseline'
> > [mpeg4 @ 0x5555575854c0] Unable to parse option value "baseline"
> > [mpeg4 @ 0x5555575854c0] Error setting option profile to value baseline.
> > Thread 1 "ffmpeg" received signal SIGSEGV, Segmentation fault.
> > 
> > root cause:
> > If the codec has FF_CODEC_CAP_INIT_CLEANUP flag, and avcodec_open2 got an error before avctx->codec->init,
> > the ff_mpv_encode_end will face a null s->avctx.
> > ---
> >  libavcodec/mpegvideo_enc.c | 7 ++++---
> >  1 file changed, 4 insertions(+), 3 deletions(-)
> > 
> > diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
> > index 09697d89c8..a79309d1b9 100644
> > --- a/libavcodec/mpegvideo_enc.c
> > +++ b/libavcodec/mpegvideo_enc.c
> > @@ -1078,9 +1078,10 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
> >          av_frame_free(&s->tmp_frames[i]);
> >  
> >      ff_free_picture_tables(&s->new_picture);
> > -    ff_mpeg_unref_picture(s->avctx, &s->new_picture);
> > -
> > -    av_freep(&s->avctx->stats_out);
> > +    if (s->avctx) {
> 
> Judging by the av_freep(&avctx->extradata) call earlier in the function
> i assume s->avctx is meant to be the same as avctx, which is guaranteed
> to not be NULL, so you can use that instead.

ive just posted a patch which changes these and more s->avctx in the file

thx

[...]
Guangxin Xu Aug. 30, 2020, 9:07 a.m. UTC | #5
thanks, James and Michael.
Are we ready to merge this?
thanks

On Wed, Aug 26, 2020 at 5:51 AM Michael Niedermayer <michael@niedermayer.cc>
wrote:

> On Tue, Aug 25, 2020 at 11:37:59AM -0300, James Almer wrote:
> > On 8/25/2020 6:35 AM, Xu Guangxin wrote:
> > > Steps to reproduce:
> > > 1. ./configure --enable-debug=3 --disable-libx264 && make install
> > > 2. ffmpeg -i input.mp4 -profile:v baseline output.mp4 -y
> > >
> > > you will see a crash like this:
> > > [mpeg4 @ 0x5555575854c0] [Eval @ 0x7fffffffbf80] Undefined constant or
> missing '(' in 'baseline'
> > > [mpeg4 @ 0x5555575854c0] Unable to parse option value "baseline"
> > > [mpeg4 @ 0x5555575854c0] Error setting option profile to value
> baseline.
> > > Thread 1 "ffmpeg" received signal SIGSEGV, Segmentation fault.
> > >
> > > root cause:
> > > If the codec has FF_CODEC_CAP_INIT_CLEANUP flag, and avcodec_open2 got
> an error before avctx->codec->init,
> > > the ff_mpv_encode_end will face a null s->avctx.
> > > ---
> > >  libavcodec/mpegvideo_enc.c | 7 ++++---
> > >  1 file changed, 4 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
> > > index 09697d89c8..a79309d1b9 100644
> > > --- a/libavcodec/mpegvideo_enc.c
> > > +++ b/libavcodec/mpegvideo_enc.c
> > > @@ -1078,9 +1078,10 @@ av_cold int ff_mpv_encode_end(AVCodecContext
> *avctx)
> > >          av_frame_free(&s->tmp_frames[i]);
> > >
> > >      ff_free_picture_tables(&s->new_picture);
> > > -    ff_mpeg_unref_picture(s->avctx, &s->new_picture);
> > > -
> > > -    av_freep(&s->avctx->stats_out);
> > > +    if (s->avctx) {
> >
> > Judging by the av_freep(&avctx->extradata) call earlier in the function
> > i assume s->avctx is meant to be the same as avctx, which is guaranteed
> > to not be NULL, so you can use that instead.
>
> ive just posted a patch which changes these and more s->avctx in the file
>
> thx
>
> [...]
> --
> Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> There will always be a question for which you do not know the correct
> answer.
> _______________________________________________
> 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 Aug. 30, 2020, 6:21 p.m. UTC | #6
On Sun, Aug 30, 2020 at 05:07:03PM +0800, Guangxin Xu wrote:
> thanks, James and Michael.
> Are we ready to merge this?

ive applied the avctx change patch which should fix this

thx

[...]
diff mbox series

Patch

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 09697d89c8..a79309d1b9 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -1078,9 +1078,10 @@  av_cold int ff_mpv_encode_end(AVCodecContext *avctx)
         av_frame_free(&s->tmp_frames[i]);
 
     ff_free_picture_tables(&s->new_picture);
-    ff_mpeg_unref_picture(s->avctx, &s->new_picture);
-
-    av_freep(&s->avctx->stats_out);
+    if (s->avctx) {
+        ff_mpeg_unref_picture(s->avctx, &s->new_picture);
+        av_freep(&s->avctx->stats_out);
+    }
     av_freep(&s->ac_stats);
 
     if(s->q_chroma_intra_matrix   != s->q_intra_matrix  ) av_freep(&s->q_chroma_intra_matrix);