diff mbox series

[FFmpeg-devel,1/4] avfilter/avfiltergraph: Fix use-after-free when inserting auto-converter

Message ID AM7PR03MB6660B293F850D3A099D7CF018FB29@AM7PR03MB6660.eurprd03.prod.outlook.com
State Accepted
Headers show
Series [FFmpeg-devel,1/4] avfilter/avfiltergraph: Fix use-after-free when inserting auto-converter | expand

Checks

Context Check Description
andriy/configurex86 warning Failed to apply patch
andriy/configureppc warning Failed to apply patch

Commit Message

Andreas Rheinhardt Oct. 8, 2021, 7:59 a.m. UTC
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>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavfilter/avfiltergraph.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

Comments

Paul B Mahol Oct. 8, 2021, 9:04 a.m. UTC | #1
LGTM
diff mbox series

Patch

diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index e536abef8e..0e3de3cd56 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,