aboutsummaryrefslogtreecommitdiffstats
path: root/libavfilter/avfiltergraph.c
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2021-10-08 08:55:56 +0200
committerAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2021-10-08 12:06:00 +0200
commit5e1dac380bea627e5b7751e07bdabc0f4ee139c2 (patch)
treefacc9dbf3f15a7b226fe89af4e38986ca3d669d0 /libavfilter/avfiltergraph.c
parent4ff884069787161138e604b7aae495d27c457287 (diff)
downloadffmpeg-5e1dac380bea627e5b7751e07bdabc0f4ee139c2.tar.gz
avfilter/avfiltergraph: Fix use-after-free when inserting auto-converter
When inserting an auto-resampler, it may be that the configuration of the filters that the auto-resampler is supposed to connect is already partially merged, i.e. converter->inputs[0].incfg.foo and converter->outputs[0].outcfg.foo (where foo is one of formats, samplerates, channel_layouts) can coincide. Therefore merging the converter filter's input link might modify the outcfg of the converter' outlink. Yet the current code in avfiltergraph.c used pointers from before merging the inlink for merging the outlink, leading to a use-after-free in command lines like: $ ffmpeg -f lavfi -i anullsrc=cl=stereo -lavfi channelsplit,axcorrelate -f null - Fix this by not using outdated values when merging the outlink. This is a regression since 85a6404d7e6c759ddf71d6374812d7ff719728ec. Found-by: Paul B Mahol <onemda@gmail.com> Reviewed-by: Paul B Mahol <onemda@gmail.com> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Diffstat (limited to 'libavfilter/avfiltergraph.c')
-rw-r--r--libavfilter/avfiltergraph.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index e536abef8e..b8b432e98b 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -520,14 +520,13 @@ static int query_formats(AVFilterGraph *graph, void *log_ctx)
av_assert0(outlink-> incfg.channel_layouts->refcount > 0);
av_assert0(outlink->outcfg.channel_layouts->refcount > 0);
}
+#define MERGE(merger, link) \
+ ((merger)->merge(FF_FIELD_AT(void *, (merger)->offset, (link)->incfg), \
+ FF_FIELD_AT(void *, (merger)->offset, (link)->outcfg)))
for (neg_step = 0; neg_step < neg->nb_mergers; neg_step++) {
const AVFilterFormatsMerger *m = &neg->mergers[neg_step];
- void *ia = FF_FIELD_AT(void *, m->offset, inlink->incfg);
- void *ib = FF_FIELD_AT(void *, m->offset, inlink->outcfg);
- void *oa = FF_FIELD_AT(void *, m->offset, outlink->incfg);
- void *ob = FF_FIELD_AT(void *, m->offset, outlink->outcfg);
- if ((ret = m->merge(ia, ib)) <= 0 ||
- (ret = m->merge(oa, ob)) <= 0) {
+ if ((ret = MERGE(m, inlink)) <= 0 ||
+ (ret = MERGE(m, outlink)) <= 0) {
if (ret < 0)
return ret;
av_log(log_ctx, AV_LOG_ERROR,