diff mbox

[FFmpeg-devel,1/2] avformat/utils: free existing extradata before trying to allocate a new one

Message ID 20180306044237.10388-1-jamrial@gmail.com
State Accepted
Commit 0ca33b1d4eb2a2a2e78ff3a37f1647917635b0d2
Headers show

Commit Message

James Almer March 6, 2018, 4:42 a.m. UTC
This prevents leaks in the rare cases the function is called when extradata
already exists.

Signed-off-by: James Almer <jamrial@gmail.com>
---
 libavformat/utils.c | 1 +
 1 file changed, 1 insertion(+)

Comments

Paul B Mahol March 6, 2018, 2:29 p.m. UTC | #1
On 3/6/18, James Almer <jamrial@gmail.com> wrote:
> This prevents leaks in the rare cases the function is called when extradata
> already exists.
>
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
>  libavformat/utils.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/libavformat/utils.c b/libavformat/utils.c
> index 72531d4185..31340a484b 100644
> --- a/libavformat/utils.c
> +++ b/libavformat/utils.c
> @@ -3245,6 +3245,7 @@ int ff_alloc_extradata(AVCodecParameters *par, int
> size)
>  {
>      int ret;
>
> +    av_freep(&par->extradata);
>      if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
>          par->extradata = NULL;
>          par->extradata_size = 0;
> --
> 2.16.2
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>

lgtm
James Almer March 6, 2018, 10:16 p.m. UTC | #2
On 3/6/2018 11:29 AM, Paul B Mahol wrote:
> On 3/6/18, James Almer <jamrial@gmail.com> wrote:
>> This prevents leaks in the rare cases the function is called when extradata
>> already exists.
>>
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>>  libavformat/utils.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/libavformat/utils.c b/libavformat/utils.c
>> index 72531d4185..31340a484b 100644
>> --- a/libavformat/utils.c
>> +++ b/libavformat/utils.c
>> @@ -3245,6 +3245,7 @@ int ff_alloc_extradata(AVCodecParameters *par, int
>> size)
>>  {
>>      int ret;
>>
>> +    av_freep(&par->extradata);
>>      if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
>>          par->extradata = NULL;
>>          par->extradata_size = 0;
>> --
>> 2.16.2
>>
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
> 
> lgtm

Patchset pushed. Thanks.
Michael Niedermayer March 7, 2018, 1:47 a.m. UTC | #3
On Tue, Mar 06, 2018 at 01:42:36AM -0300, James Almer wrote:
> This prevents leaks in the rare cases the function is called when extradata
> already exists.
> 
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
>  libavformat/utils.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/libavformat/utils.c b/libavformat/utils.c
> index 72531d4185..31340a484b 100644
> --- a/libavformat/utils.c
> +++ b/libavformat/utils.c
> @@ -3245,6 +3245,7 @@ int ff_alloc_extradata(AVCodecParameters *par, int size)
>  {
>      int ret;
>  
> +    av_freep(&par->extradata);
>      if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
>          par->extradata = NULL;
>          par->extradata_size = 0;

This causes memory corruption
...
[mpegts @ 0x7f8c74000a80] PES packet size mismatch
*** Error in `./ffplay': double free or corruption (fasttop): 0x00007f8c7402d9c0 ***
Aborted (core dumped)

I think this should not have been applied so quickly, i tested it as soon as i
had time and saw it but it was applied already

If it helps i can debug the cases i see to find out which calls cause them but
someone will still have to review all call sites probably for this change to
be safe


[...]
James Almer March 7, 2018, 2:03 a.m. UTC | #4
On 3/6/2018 10:47 PM, Michael Niedermayer wrote:
> On Tue, Mar 06, 2018 at 01:42:36AM -0300, James Almer wrote:
>> This prevents leaks in the rare cases the function is called when extradata
>> already exists.
>>
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>>  libavformat/utils.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/libavformat/utils.c b/libavformat/utils.c
>> index 72531d4185..31340a484b 100644
>> --- a/libavformat/utils.c
>> +++ b/libavformat/utils.c
>> @@ -3245,6 +3245,7 @@ int ff_alloc_extradata(AVCodecParameters *par, int size)
>>  {
>>      int ret;
>>  
>> +    av_freep(&par->extradata);
>>      if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
>>          par->extradata = NULL;
>>          par->extradata_size = 0;
> 
> This causes memory corruption
> ...
> [mpegts @ 0x7f8c74000a80] PES packet size mismatch
> *** Error in `./ffplay': double free or corruption (fasttop): 0x00007f8c7402d9c0 ***
> Aborted (core dumped)

Is something freeing extradata and leaving a dangling pointer before
eventually calling ff_alloc_extradata()?
At least the two calls in mpegts.c don't seem to do that.

> 
> I think this should not have been applied so quickly, i tested it as soon as i
> had time and saw it but it was applied already

Fate passed when i tested it, and i got a positive review from the
author of the function in question, that's why i pushed it. Sorry.

> 
> If it helps i can debug the cases i see to find out which calls cause them but
> someone will still have to review all call sites probably for this change to
> be safe

Yes, help would be welcome. Crashes like this probably hint at frees
leaving dangling pointers across the codebase.

> 
> 
> [...]
> 
> 
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
Michael Niedermayer March 7, 2018, 2:29 a.m. UTC | #5
On Tue, Mar 06, 2018 at 11:03:55PM -0300, James Almer wrote:
> On 3/6/2018 10:47 PM, Michael Niedermayer wrote:
> > On Tue, Mar 06, 2018 at 01:42:36AM -0300, James Almer wrote:
> >> This prevents leaks in the rare cases the function is called when extradata
> >> already exists.
> >>
> >> Signed-off-by: James Almer <jamrial@gmail.com>
> >> ---
> >>  libavformat/utils.c | 1 +
> >>  1 file changed, 1 insertion(+)
> >>
> >> diff --git a/libavformat/utils.c b/libavformat/utils.c
> >> index 72531d4185..31340a484b 100644
> >> --- a/libavformat/utils.c
> >> +++ b/libavformat/utils.c
> >> @@ -3245,6 +3245,7 @@ int ff_alloc_extradata(AVCodecParameters *par, int size)
> >>  {
> >>      int ret;
> >>  
> >> +    av_freep(&par->extradata);
> >>      if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
> >>          par->extradata = NULL;
> >>          par->extradata_size = 0;
> > 
> > This causes memory corruption
> > ...
> > [mpegts @ 0x7f8c74000a80] PES packet size mismatch
> > *** Error in `./ffplay': double free or corruption (fasttop): 0x00007f8c7402d9c0 ***
> > Aborted (core dumped)
> 
> Is something freeing extradata and leaving a dangling pointer before
> eventually calling ff_alloc_extradata()?
> At least the two calls in mpegts.c don't seem to do that.
> 
> > 
> > I think this should not have been applied so quickly, i tested it as soon as i
> > had time and saw it but it was applied already
> 
> Fate passed when i tested it, and i got a positive review from the
> author of the function in question, that's why i pushed it. Sorry.
> 
> > 
> > If it helps i can debug the cases i see to find out which calls cause them but
> > someone will still have to review all call sites probably for this change to
> > be safe
> 
> Yes, help would be welcome. Crashes like this probably hint at frees
> leaving dangling pointers across the codebase.

heres some valgrind output

==8248== Thread 15:peated 5 times
==8248== Invalid free() / delete / delete[] / realloc()
==8248==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==8248==    by 0x75B0FE: ff_get_extradata (in ffmpeg/ffplay_g)
==8248==    by 0x68F1E1: ff_mp4_read_dec_config_descr (in ffmpeg/ffplay_g)
==8248==    by 0x6D7A2C: m4sl_cb (in ffmpeg/ffplay_g)
==8248==    by 0x6D6539: handle_packet (in ffmpeg/ffplay_g)
==8248==    by 0x6D69B3: handle_packets (in ffmpeg/ffplay_g)
==8248==    by 0x6D6A53: mpegts_read_packet (in ffmpeg/ffplay_g)
==8248==    by 0x754AA1: ff_read_packet (in ffmpeg/ffplay_g)
==8248==    by 0x75E32F: avformat_find_stream_info (in ffmpeg/ffplay_g)
==8248==    by 0x4B86D8: read_thread (in ffmpeg/ffplay_g)
==8248==    by 0x74742EC: SDL_RunThread (SDL_thread.c:282)
==8248==    by 0x74D21A8: RunThread (SDL_systhread.c:75)
==8248==  Address 0x3085a000 is 0 bytes inside a block of size 88 free'd
==8248==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==8248==    by 0x68F1CD: ff_mp4_read_dec_config_descr (in ffmpeg/ffplay_g)
==8248==    by 0x6D7A2C: m4sl_cb (in ffmpeg/ffplay_g)
==8248==    by 0x6D6539: handle_packet (in ffmpeg/ffplay_g)
==8248==    by 0x6D69B3: handle_packets (in ffmpeg/ffplay_g)
==8248==    by 0x6D6A53: mpegts_read_packet (in ffmpeg/ffplay_g)
==8248==    by 0x754AA1: ff_read_packet (in ffmpeg/ffplay_g)
==8248==    by 0x75E32F: avformat_find_stream_info (in ffmpeg/ffplay_g)
==8248==    by 0x4B86D8: read_thread (in ffmpeg/ffplay_g)
==8248==    by 0x74742EC: SDL_RunThread (SDL_thread.c:282)
==8248==    by 0x74D21A8: RunThread (SDL_systhread.c:75)
==8248==    by 0xB8A2183: start_thread (pthread_create.c:312)
==8248== 
    Last message repeated 5 times

i can provide a better debug output tomorrow, need to go afk now
    
    
[...]
James Almer March 7, 2018, 2:31 a.m. UTC | #6
On 3/6/2018 11:29 PM, Michael Niedermayer wrote:
> On Tue, Mar 06, 2018 at 11:03:55PM -0300, James Almer wrote:
>> On 3/6/2018 10:47 PM, Michael Niedermayer wrote:
>>> On Tue, Mar 06, 2018 at 01:42:36AM -0300, James Almer wrote:
>>>> This prevents leaks in the rare cases the function is called when extradata
>>>> already exists.
>>>>
>>>> Signed-off-by: James Almer <jamrial@gmail.com>
>>>> ---
>>>>  libavformat/utils.c | 1 +
>>>>  1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/libavformat/utils.c b/libavformat/utils.c
>>>> index 72531d4185..31340a484b 100644
>>>> --- a/libavformat/utils.c
>>>> +++ b/libavformat/utils.c
>>>> @@ -3245,6 +3245,7 @@ int ff_alloc_extradata(AVCodecParameters *par, int size)
>>>>  {
>>>>      int ret;
>>>>  
>>>> +    av_freep(&par->extradata);
>>>>      if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
>>>>          par->extradata = NULL;
>>>>          par->extradata_size = 0;
>>>
>>> This causes memory corruption
>>> ...
>>> [mpegts @ 0x7f8c74000a80] PES packet size mismatch
>>> *** Error in `./ffplay': double free or corruption (fasttop): 0x00007f8c7402d9c0 ***
>>> Aborted (core dumped)
>>
>> Is something freeing extradata and leaving a dangling pointer before
>> eventually calling ff_alloc_extradata()?
>> At least the two calls in mpegts.c don't seem to do that.
>>
>>>
>>> I think this should not have been applied so quickly, i tested it as soon as i
>>> had time and saw it but it was applied already
>>
>> Fate passed when i tested it, and i got a positive review from the
>> author of the function in question, that's why i pushed it. Sorry.
>>
>>>
>>> If it helps i can debug the cases i see to find out which calls cause them but
>>> someone will still have to review all call sites probably for this change to
>>> be safe
>>
>> Yes, help would be welcome. Crashes like this probably hint at frees
>> leaving dangling pointers across the codebase.
> 
> heres some valgrind output
> 
> ==8248== Thread 15:peated 5 times
> ==8248== Invalid free() / delete / delete[] / realloc()
> ==8248==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
> ==8248==    by 0x75B0FE: ff_get_extradata (in ffmpeg/ffplay_g)
> ==8248==    by 0x68F1E1: ff_mp4_read_dec_config_descr (in ffmpeg/ffplay_g)

Figures. The patch i sent a few minutes ago should fix it then.

> ==8248==    by 0x6D7A2C: m4sl_cb (in ffmpeg/ffplay_g)
> ==8248==    by 0x6D6539: handle_packet (in ffmpeg/ffplay_g)
> ==8248==    by 0x6D69B3: handle_packets (in ffmpeg/ffplay_g)
> ==8248==    by 0x6D6A53: mpegts_read_packet (in ffmpeg/ffplay_g)
> ==8248==    by 0x754AA1: ff_read_packet (in ffmpeg/ffplay_g)
> ==8248==    by 0x75E32F: avformat_find_stream_info (in ffmpeg/ffplay_g)
> ==8248==    by 0x4B86D8: read_thread (in ffmpeg/ffplay_g)
> ==8248==    by 0x74742EC: SDL_RunThread (SDL_thread.c:282)
> ==8248==    by 0x74D21A8: RunThread (SDL_systhread.c:75)
> ==8248==  Address 0x3085a000 is 0 bytes inside a block of size 88 free'd
> ==8248==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
> ==8248==    by 0x68F1CD: ff_mp4_read_dec_config_descr (in ffmpeg/ffplay_g)
> ==8248==    by 0x6D7A2C: m4sl_cb (in ffmpeg/ffplay_g)
> ==8248==    by 0x6D6539: handle_packet (in ffmpeg/ffplay_g)
> ==8248==    by 0x6D69B3: handle_packets (in ffmpeg/ffplay_g)
> ==8248==    by 0x6D6A53: mpegts_read_packet (in ffmpeg/ffplay_g)
> ==8248==    by 0x754AA1: ff_read_packet (in ffmpeg/ffplay_g)
> ==8248==    by 0x75E32F: avformat_find_stream_info (in ffmpeg/ffplay_g)
> ==8248==    by 0x4B86D8: read_thread (in ffmpeg/ffplay_g)
> ==8248==    by 0x74742EC: SDL_RunThread (SDL_thread.c:282)
> ==8248==    by 0x74D21A8: RunThread (SDL_systhread.c:75)
> ==8248==    by 0xB8A2183: start_thread (pthread_create.c:312)
> ==8248== 
>     Last message repeated 5 times
> 
> i can provide a better debug output tomorrow, need to go afk now
>     
>     
> [...]
> 
> 
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
diff mbox

Patch

diff --git a/libavformat/utils.c b/libavformat/utils.c
index 72531d4185..31340a484b 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -3245,6 +3245,7 @@  int ff_alloc_extradata(AVCodecParameters *par, int size)
 {
     int ret;
 
+    av_freep(&par->extradata);
     if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
         par->extradata = NULL;
         par->extradata_size = 0;