diff mbox series

[FFmpeg-devel,3/3] avformat/mlvdec: Only store dimensions after having validated them

Message ID 20200810011023.17540-3-andreas.rheinhardt@gmail.com
State Accepted
Commit d661cfc184bcf0bb13bb11fdba6f5d4493675f85
Headers show
Series [FFmpeg-devel,1/3] avformat/mlvdec: Check for existence of AVIOContext before using it
Related show

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Andreas Rheinhardt Aug. 10, 2020, 1:10 a.m. UTC
Otherwise it might happen that invalid dimensions are used when reading
a video packet; this might lead to undefined overflow.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
 libavformat/mlvdec.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

Comments

Paul B Mahol Aug. 19, 2020, 6:15 p.m. UTC | #1
On 8/10/20, Andreas Rheinhardt <andreas.rheinhardt@gmail.com> wrote:
> Otherwise it might happen that invalid dimensions are used when reading
> a video packet; this might lead to undefined overflow.
>
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
> ---
>  libavformat/mlvdec.c | 20 +++++++++++---------
>  1 file changed, 11 insertions(+), 9 deletions(-)
>

LGTM
diff mbox series

Patch

diff --git a/libavformat/mlvdec.c b/libavformat/mlvdec.c
index 50913fa685..f08aabf4e0 100644
--- a/libavformat/mlvdec.c
+++ b/libavformat/mlvdec.c
@@ -132,23 +132,25 @@  static int scan_file(AVFormatContext *avctx, AVStream *vst, AVStream *ast, int f
             break;
         size -= 16;
         if (vst && type == MKTAG('R','A','W','I') && size >= 164) {
-            vst->codecpar->width  = avio_rl16(pb);
-            vst->codecpar->height = avio_rl16(pb);
-            ret = av_image_check_size(vst->codecpar->width, vst->codecpar->height, 0, avctx);
+            unsigned width  = avio_rl16(pb);
+            unsigned height = avio_rl16(pb);
+            unsigned bits_per_coded_sample;
+            ret = av_image_check_size(width, height, 0, avctx);
             if (ret < 0)
                 return ret;
             if (avio_rl32(pb) != 1)
                 avpriv_request_sample(avctx, "raw api version");
             avio_skip(pb, 20); // pointer, width, height, pitch, frame_size
-            vst->codecpar->bits_per_coded_sample = avio_rl32(pb);
-            if (vst->codecpar->bits_per_coded_sample < 0 ||
-                vst->codecpar->bits_per_coded_sample > (INT_MAX - 7) / (vst->codecpar->width * vst->codecpar->height)) {
+            bits_per_coded_sample = avio_rl32(pb);
+            if (bits_per_coded_sample > (INT_MAX - 7) / (width * height)) {
                 av_log(avctx, AV_LOG_ERROR,
-                       "invalid bits_per_coded_sample %d (size: %dx%d)\n",
-                       vst->codecpar->bits_per_coded_sample,
-                       vst->codecpar->width, vst->codecpar->height);
+                       "invalid bits_per_coded_sample %u (size: %ux%u)\n",
+                       bits_per_coded_sample, width, height);
                 return AVERROR_INVALIDDATA;
             }
+            vst->codecpar->width  = width;
+            vst->codecpar->height = height;
+            vst->codecpar->bits_per_coded_sample = bits_per_coded_sample;
             avio_skip(pb, 8 + 16 + 24); // black_level, white_level, xywh, active_area, exposure_bias
             if (avio_rl32(pb) != 0x2010100) /* RGGB */
                 avpriv_request_sample(avctx, "cfa_pattern");