History

avfilter/af_channelmap: Fix double-free of AVFilterChannelLayouts on error

The query_formats function of the channelmap filter tries to allocate a list of channel layouts which on success are attached to more permanent objects (an AVFilterLink) for storage afterwards. If attaching succeeds, the link becomes one of the common owners (in this case, the only owner) of the list. Yet if the list has been successfully attached to the link and an error happens lateron, the list was manually freed, which is wrong, because it is owned by its link so that the link's pointer to the list will become dangling and there will be a double-free/use-after-free when the link is later cleaned up automatically. This commit fixes this by removing the custom freeing code; this will temporarily add a leaking codepath (if attaching the list fails, the list will leak), but this will be fixed soon by making sure that an AVFilterChannelLayouts without owner will be automatically freed when attaching it to an AVFilterLink fails.

Andreas Rheinhardt committed 6 years ago

Commit 44bcd6f1 parent fd1a2a51 file · +7 −17Browse files

Unified · Split

libavfilter/af_channelmap.c+7−17
@@ -280,28 +280,18 @@ static av_cold int channelmap_init(AVFilterContext *ctx) · 279 unmodified lines
280280 static int channelmap_query_formats(AVFilterContext *ctx)
281281 {
282282 ChannelMapContext *s = ctx->priv;
283− AVFilterChannelLayouts *layouts;
284283 AVFilterChannelLayouts *channel_layouts = NULL;
285284 int ret;
286285
287− layouts = ff_all_channel_counts();
288− if (!layouts) {
289− ret = AVERROR(ENOMEM);
290− goto fail;
291− }
292− if ((ret = ff_add_channel_layout (&channel_layouts, s->output_layout )) < 0 ||
293− (ret = ff_set_common_formats (ctx , ff_planar_sample_fmts() )) < 0 ||
286+ if ((ret = ff_set_common_formats (ctx, ff_planar_sample_fmts())) < 0 ||
294287 (ret = ff_set_common_samplerates (ctx , ff_all_samplerates() )) < 0 ||
295− (ret = ff_channel_layouts_ref (layouts , &ctx->inputs[0]->out_channel_layouts)) < 0 ||
296− (ret = ff_channel_layouts_ref (channel_layouts , &ctx->outputs[0]->in_channel_layouts)) < 0)
297− goto fail;
288+ (ret = ff_add_channel_layout(&channel_layouts, s->output_layout)) < 0 ||
289+ (ret = ff_channel_layouts_ref(channel_layouts,
290+ &ctx->outputs[0]->in_channel_layouts)) < 0)
291+ return ret;
298292
299− return 0;
300−fail:
301− if (layouts)
302− av_freep(&layouts->channel_layouts);
303− av_freep(&layouts);
304− return ret;
293+ return ff_channel_layouts_ref(ff_all_channel_counts(),
294+ &ctx->inputs[0]->out_channel_layouts);
305295 }
306296
307297 static int channelmap_filter_frame(AVFilterLink *inlink, AVFrame *buf)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t