diff mbox series

[FFmpeg-devel,02/25] avformat/matroskaenc: Don't open BlockGroup twice

Message ID AM7PR03MB66609E21A5374B4D0BE53A7C8F569@AM7PR03MB6660.eurprd03.prod.outlook.com
State Accepted
Commit 5e186f9693db11dc720afa867659afee978b02d8
Headers show
Series [FFmpeg-devel,01/25] avformat/matroskaenc: Fix potential overflow | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_aarch64_jetson success Make finished
andriy/make_fate_aarch64_jetson success Make fate finished
andriy/make_ppc success Make finished
andriy/make_fate_ppc success Make fate finished

Commit Message

Andreas Rheinhardt Jan. 16, 2022, 11:03 p.m. UTC
This would happen in case non-WebVTT-subtitles had BlockAdditional
or DiscardPadding side-data. Given that these are not accounted for
in the length of the outer BlockGroup (which is a quite sharp upper
bound) it is possible for the outer BlockGroup to use an insufficient
number of bytes which leads to an assert in end_ebml_master().

Fix this by not opening a second BlockGroup inside an already opened
BlockGroup.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavformat/matroskaenc.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 1dde12a7d9..81194fd28d 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -2095,6 +2095,7 @@  static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
     int64_t discard_padding = 0;
     unsigned track_number = track->track_num;
     ebml_master block_group, block_additions, block_more;
+    int blockgroup_already_opened = blockid == MATROSKA_ID_BLOCK;
 
     ts += track->ts_offset;
 
@@ -2141,7 +2142,7 @@  static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
     side_data = av_packet_get_side_data(pkt,
                                         AV_PKT_DATA_SKIP_SAMPLES,
                                         &side_data_size);
-    if (side_data && side_data_size >= 10) {
+    if (side_data && side_data_size >= 10 && !blockgroup_already_opened) {
         discard_padding = av_rescale_q(AV_RL32(side_data + 4),
                                        (AVRational){1, par->sample_rate},
                                        (AVRational){1, 1000000000});
@@ -2152,7 +2153,8 @@  static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
                                         &side_data_size);
     if (side_data) {
         // Only the Codec-specific BlockMore (id == 1) is currently supported.
-        if (side_data_size < 8 || (additional_id = AV_RB64(side_data)) != 1) {
+        if (side_data_size < 8 || (additional_id = AV_RB64(side_data)) != 1 ||
+            blockgroup_already_opened) {
             side_data_size = 0;
         } else {
             side_data      += 8;