Opened 3 years ago

Closed 3 years ago

#8227 closed defect (invalid)

A double-free bug in the source file libavfilter/lavfutils.c

Reported by: wurongxin Owned by:
Priority: normal Component: undetermined
Version: git-master Keywords:
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug:
How to reproduce:

% ffmpeg -i input ... output
ffmpeg version
built on ...

Patches should be submitted to the ffmpeg-devel mailing list and not this bug tracker.

In the source file https://github.com/FFmpeg/FFmpeg/blob/master/libavfilter/lavfutils.c, there is a possible double-free bug. At Line 85, it will invoke the function av_read_frame and would free the variable pkt->side_data. At Line 110, it will invoke the function av_packet_unref and would free the variable pkt->side_data again.

85.	    ret = av_read_frame(format_ctx, &pkt);
86.	    if (ret < 0) {
87.	        av_log(log_ctx, AV_LOG_ERROR, "Failed to read frame from file\n");
88.	        goto end;
89.	    }
	…
109.	end:
110.	    av_packet_unref(&pkt);

To see how the function av_read_frame can free the pkt->side_data, please see the following code in the source file https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/utils.c. At Line 1854, it will invoke the function av_packet_unref and would free pkt->side_data here.

1777.	int av_read_frame(AVFormatContext *s, AVPacket *pkt)
1778.	{
	…
1850.	        ret = ff_packet_list_put(&s->internal->packet_buffer,
1851.	                                 &s->internal->packet_buffer_end,
1852.	                                 pkt, 0);
1853.	        if (ret < 0) {
1854.	            av_packet_unref(pkt);
1855.	            return ret;
1856.	        }

To see how the function av_packet_unref would free pkt->side_data, please see the following code in the source file https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/avpacket.c. At Line 601, it is the site where it free pkt->side_data.

599.	void av_packet_unref(AVPacket *pkt)
600.	{
601.	            av_packet_free_side_data(pkt);
602.	    av_buffer_unref(&pkt->buf);
603.	    av_init_packet(pkt);
604.	    pkt->data = NULL;
605.	    pkt->size = 0;
606.	}

Change History (1)

comment:1 by mkver, 3 years ago

Component: avfilterundetermined
Resolution: invalid
Status: newclosed

Using av_packet_unref() after av_packet_unref() is safe, because av_packet_free_side_data uses av_freep(), i.e. it not only frees the side-data, but also resets the pointer to said side data (and the counter for the number of side-data elements).

Note: See TracTickets for help on using tickets.