diff mbox series

[FFmpeg-devel,4/5] avformat/matroskaenc: Check WebVTT subtitles for overflow

Message ID 20210317235958.1308987-4-andreas.rheinhardt@gmail.com
State New
Headers show
Series [FFmpeg-devel,1/5] avcodec/avpacket: Improve overflow checks when packing dictionary
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Andreas Rheinhardt March 17, 2021, 11:59 p.m. UTC
The destination here is an dynamic buffer which is restricted to
INT_MAX, so check for that.

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

Patch

diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 5d8d4cd646..4931988efd 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -2133,7 +2133,7 @@  static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, const AVPac
     mkv_track *track = &mkv->tracks[pkt->stream_index];
     ebml_master blockgroup;
     buffer_size_t id_size, settings_size;
-    int size;
+    int size = pkt->size + 2;
     const char *id, *settings;
     int64_t ts = track->write_dts ? pkt->dts : pkt->pts;
     const int flags = 0;
@@ -2141,12 +2141,17 @@  static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, const AVPac
     id = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_IDENTIFIER,
                                  &id_size);
     id = id ? id : "";
+    if (id_size > INT_MAX - size)
+        return AVERROR(ERANGE);
+    size += id_size;
 
     settings = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_SETTINGS,
                                        &settings_size);
     settings = settings ? settings : "";
+    if (settings_size > INT_MAX - size)
+        return AVERROR(ERANGE);
 
-    size = id_size + 1 + settings_size + 1 + pkt->size;
+    size += settings_size;
 
     /* The following string is identical to the one in mkv_write_block so that
      * only one copy needs to exist in binaries. */
@@ -2170,7 +2175,7 @@  static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, const AVPac
     put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, pkt->duration);
     end_ebml_master(pb, blockgroup);
 
-    return pkt->duration;
+    return 0;
 }
 
 static int mkv_end_cluster(AVFormatContext *s)
@@ -2341,7 +2346,9 @@  static int mkv_write_packet_internal(AVFormatContext *s, const AVPacket *pkt)
         }
     } else {
         if (par->codec_id == AV_CODEC_ID_WEBVTT) {
-            duration = mkv_write_vtt_blocks(s, pb, pkt);
+            ret = mkv_write_vtt_blocks(s, pb, pkt);
+            if (ret < 0)
+                return ret;
         } else {
             ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP,
                                                        mkv_blockgroup_size(pkt->size,