aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-01-23 17:08:27 +0100
committerAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-05-20 00:52:54 +0200
commit7f2ab227e0382736126da9ab0704fcdc76b4b664 (patch)
tree6d20cc7b469e79d7348769a791a67452d1f881b3
parent703473ec04311016d2a1636ae9a91d2a1234eb91 (diff)
downloadffmpeg-7f2ab227e0382736126da9ab0704fcdc76b4b664.tar.gz
avformat/matroskaenc: Check for reformatting errors
This is needed especially for AV1: If a reformatting error happens (e.g. if the length field of an OBU contained in the current packet indicates that said OBU extends beyond the current packet), the data pointer is still NULL, yet the size is unchanged, so that writing the data leads to a segmentation fault. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com> Signed-off-by: James Almer <jamrial@gmail.com> (cherry picked from commit 58428bef4b2c053f47dce35157fb96833ba8efea)
-rw-r--r--libavformat/matroskaenc.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 2e63b90b28..acc7090e77 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -2108,13 +2108,13 @@ fail:
return ret;
}
-static void mkv_write_block(AVFormatContext *s, AVIOContext *pb,
- uint32_t blockid, AVPacket *pkt, int keyframe)
+static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
+ uint32_t blockid, AVPacket *pkt, int keyframe)
{
MatroskaMuxContext *mkv = s->priv_data;
AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar;
uint8_t *data = NULL, *side_data = NULL;
- int offset = 0, size = pkt->size, side_data_size = 0;
+ int err = 0, offset = 0, size = pkt->size, side_data_size = 0;
int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
uint64_t additional_id = 0;
int64_t discard_padding = 0;
@@ -2133,22 +2133,24 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb,
mkv->cluster_pos, track_number, keyframe != 0);
if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size > 0 &&
(AV_RB24(par->extradata) == 1 || AV_RB32(par->extradata) == 1))
- ff_avc_parse_nal_units_buf(pkt->data, &data, &size);
+ err = ff_avc_parse_nal_units_buf(pkt->data, &data, &size);
else if (par->codec_id == AV_CODEC_ID_HEVC && par->extradata_size > 6 &&
(AV_RB24(par->extradata) == 1 || AV_RB32(par->extradata) == 1))
/* extradata is Annex B, assume the bitstream is too and convert it */
- ff_hevc_annexb2mp4_buf(pkt->data, &data, &size, 0, NULL);
+ err = ff_hevc_annexb2mp4_buf(pkt->data, &data, &size, 0, NULL);
else if (par->codec_id == AV_CODEC_ID_AV1)
- ff_av1_filter_obus_buf(pkt->data, &data, &size);
+ err = ff_av1_filter_obus_buf(pkt->data, &data, &size);
else if (par->codec_id == AV_CODEC_ID_WAVPACK) {
- int ret = mkv_strip_wavpack(pkt->data, &data, &size);
- if (ret < 0) {
- av_log(s, AV_LOG_ERROR, "Error stripping a WavPack packet.\n");
- return;
- }
+ err = mkv_strip_wavpack(pkt->data, &data, &size);
} else
data = pkt->data;
+ if (err < 0) {
+ av_log(s, AV_LOG_ERROR, "Error when reformatting data of "
+ "a packet from stream %d.\n", pkt->stream_index);
+ return err;
+ }
+
if (par->codec_id == AV_CODEC_ID_PRORES && size >= 8) {
/* Matroska specification requires to remove the first QuickTime atom
*/
@@ -2213,6 +2215,8 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb,
if ((side_data_size && additional_id == 1) || discard_padding) {
end_ebml_master(pb, block_group);
}
+
+ return 0;
}
static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
@@ -2418,7 +2422,9 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_
relative_packet_pos = avio_tell(pb);
if (par->codec_type != AVMEDIA_TYPE_SUBTITLE) {
- mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe);
+ ret = mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe);
+ if (ret < 0)
+ return ret;
if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && (par->codec_type == AVMEDIA_TYPE_VIDEO && keyframe || add_cue)) {
ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, dash_tracknum, ts, mkv->cluster_pos, relative_packet_pos, -1);
if (ret < 0) return ret;