[vlc-commits] contrib: ffmpeg: fix crash on use after free buffer in MPEG2 DXVA
Steve Lhomme
git at videolan.org
Tue Apr 27 11:46:47 UTC 2021
vlc/vlc-3.0 | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Fri Feb 12 08:45:53 2021 +0100| [c35f6712bbf133f6a1223012e63a6161c4e79d47] | committer: Hugo Beauzée-Luyssen
contrib: ffmpeg: fix crash on use after free buffer in MPEG2 DXVA
Signed-off-by: Hugo Beauzée-Luyssen <hugo at beauzee.fr>
(cherry picked from commit f43cad135a6feccd6422114a00d9bc438e9d5af9)
Signed-off-by: Hugo Beauzée-Luyssen <hugo at beauzee.fr>
> http://git.videolan.org/gitweb.cgi/vlc/vlc-3.0.git/?a=commit;h=c35f6712bbf133f6a1223012e63a6161c4e79d47
---
...g12dec-don-t-call-hw-end_frame-when-start.patch | 36 ++++++++++++++++
...g12dec-don-t-end-a-slice-without-first_sl.patch | 49 ++++++++++++++++++++++
contrib/src/ffmpeg/rules.mak | 2 +
3 files changed, 87 insertions(+)
diff --git a/contrib/src/ffmpeg/0001-avcodec-mpeg12dec-don-t-call-hw-end_frame-when-start.patch b/contrib/src/ffmpeg/0001-avcodec-mpeg12dec-don-t-call-hw-end_frame-when-start.patch
new file mode 100644
index 0000000000..138ddd83e4
--- /dev/null
+++ b/contrib/src/ffmpeg/0001-avcodec-mpeg12dec-don-t-call-hw-end_frame-when-start.patch
@@ -0,0 +1,36 @@
+From 3ca2f6e24f4422f789e6483bb782052f7f91e4e4 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Fri, 12 Feb 2021 08:20:56 +0100
+Subject: [PATCH 1/2] avcodec/mpeg12dec: don't call hw->end_frame when starting
+ second field decoding
+
+This call is unbalanced with a hwaccel->start_frame. It fixes some crashes
+because this call ends up using uninitialized memory. Decoding works as
+expected after this patch.
+---
+ libavcodec/mpeg12dec.c | 9 ---------
+ 1 file changed, 9 deletions(-)
+
+diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
+index ac5ac4bca4..88d10e9236 100644
+--- a/libavcodec/mpeg12dec.c
++++ b/libavcodec/mpeg12dec.c
+@@ -1674,15 +1674,6 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
+ return AVERROR_INVALIDDATA;
+ }
+
+- if (s->avctx->hwaccel &&
+- (s->avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD)) {
+- if ((ret = s->avctx->hwaccel->end_frame(s->avctx)) < 0) {
+- av_log(avctx, AV_LOG_ERROR,
+- "hardware accelerator failed to decode first field\n");
+- return ret;
+- }
+- }
+-
+ for (i = 0; i < 4; i++) {
+ s->current_picture.f->data[i] = s->current_picture_ptr->f->data[i];
+ if (s->picture_structure == PICT_BOTTOM_FIELD)
+--
+2.27.0.windows.1
+
diff --git a/contrib/src/ffmpeg/0002-avcodec-mpeg12dec-don-t-end-a-slice-without-first_sl.patch b/contrib/src/ffmpeg/0002-avcodec-mpeg12dec-don-t-end-a-slice-without-first_sl.patch
new file mode 100644
index 0000000000..212343d251
--- /dev/null
+++ b/contrib/src/ffmpeg/0002-avcodec-mpeg12dec-don-t-end-a-slice-without-first_sl.patch
@@ -0,0 +1,49 @@
+From 3eb70589260b6eb0e37265933a15c737023dfd7e Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at ycbcr.xyz>
+Date: Fri, 12 Feb 2021 11:10:03 +0100
+Subject: [PATCH 2/2] avcodec/mpeg12dec: don't end a slice without first_slice
+
+If first_slice is set that means the first slice/field is not started yet. We
+should not end the slice. In particular calling hwaccel->end_frame may crash as
+we're ending a frame that was not started.
+
+We also need to reset first_slice once the slice_end is finished handling
+for this check to work.
+---
+ libavcodec/mpeg12dec.c | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
+index 88d10e9236..fdf210fa1b 100644
+--- a/libavcodec/mpeg12dec.c
++++ b/libavcodec/mpeg12dec.c
+@@ -2477,13 +2477,19 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
+ s2->er.error_count += s2->thread_context[i]->er.error_count;
+ }
+
+- ret = slice_end(avctx, picture);
+- if (ret < 0)
+- return ret;
+- else if (ret) {
+- // FIXME: merge with the stuff in mpeg_decode_slice
+- if (s2->last_picture_ptr || s2->low_delay)
+- *got_output = 1;
++ if (s->first_slice) // not started yet. don't end it
++ ret = 0;
++ else {
++ ret = slice_end(avctx, picture);
++ if (ret < 0)
++ return ret;
++ else if (ret) {
++ // FIXME: merge with the stuff in mpeg_decode_slice
++ if (s2->last_picture_ptr || s2->low_delay)
++ *got_output = 1;
++ }
++ // slice ended, don't end it again later
++ s->first_slice = 1;
+ }
+ }
+ s2->pict_type = 0;
+--
+2.27.0.windows.1
+
diff --git a/contrib/src/ffmpeg/rules.mak b/contrib/src/ffmpeg/rules.mak
index 4db97585ea..7966c653d6 100644
--- a/contrib/src/ffmpeg/rules.mak
+++ b/contrib/src/ffmpeg/rules.mak
@@ -245,6 +245,8 @@ ifdef USE_FFMPEG
$(APPLY) $(SRC)/ffmpeg/0001-avcodec-hevcdec-set-the-SEI-parameters-early-on-the-.patch
$(APPLY) $(SRC)/ffmpeg/0001-avcodec-h264_slice-set-the-SEI-parameters-early-on-t.patch
$(APPLY) $(SRC)/ffmpeg/0001-avcodec-vp9-add-profile-2-10-bit-DXVA2-D3D11-decodin.patch
+ $(APPLY) $(SRC)/ffmpeg/0001-avcodec-mpeg12dec-don-t-call-hw-end_frame-when-start.patch
+ $(APPLY) $(SRC)/ffmpeg/0002-avcodec-mpeg12dec-don-t-end-a-slice-without-first_sl.patch
endif
ifdef USE_LIBAV
$(APPLY) $(SRC)/ffmpeg/libav_gsm.patch
More information about the vlc-commits
mailing list