]> git.sesse.net Git - ffmpeg/commitdiff
avcodec/tdsc: Fix tile checks
authorMichael Niedermayer <michael@niedermayer.cc>
Wed, 15 Jul 2020 20:47:50 +0000 (22:47 +0200)
committerMichael Niedermayer <michael@niedermayer.cc>
Mon, 20 Jul 2020 20:31:54 +0000 (22:31 +0200)
Fixes: out of array access
Fixes: crash.asf
Found-by: anton listov <greyfarn7@yandex.ru>
Reviewed-by: anton listov <greyfarn7@yandex.ru>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
libavcodec/tdsc.c

index eaea41c1f5cc458ac26582ecf56def6ea8cbc06f..3617911071ad1bc6f90ca7e98abcd52b42562599 100644 (file)
@@ -390,7 +390,7 @@ static int tdsc_decode_tiles(AVCodecContext *avctx, int number_tiles)
     for (i = 0; i < number_tiles; i++) {
         int tile_size;
         int tile_mode;
-        int x, y, w, h;
+        int x, y, x2, y2, w, h;
         int ret;
 
         if (bytestream2_get_bytes_left(&ctx->gbc) < 4 ||
@@ -408,20 +408,19 @@ static int tdsc_decode_tiles(AVCodecContext *avctx, int number_tiles)
         bytestream2_skip(&ctx->gbc, 4); // unknown
         x = bytestream2_get_le32(&ctx->gbc);
         y = bytestream2_get_le32(&ctx->gbc);
-        w = bytestream2_get_le32(&ctx->gbc) - x;
-        h = bytestream2_get_le32(&ctx->gbc) - y;
+        x2 = bytestream2_get_le32(&ctx->gbc);
+        y2 = bytestream2_get_le32(&ctx->gbc);
 
-        if (x >= ctx->width || y >= ctx->height) {
+        if (x < 0 || y < 0 || x2 <= x || y2 <= y ||
+            x2 > ctx->width || y2 > ctx->height
+        ) {
             av_log(avctx, AV_LOG_ERROR,
-                   "Invalid tile position (%d.%d outside %dx%d).\n",
-                   x, y, ctx->width, ctx->height);
-            return AVERROR_INVALIDDATA;
-        }
-        if (x + w > ctx->width || y + h > ctx->height) {
-            av_log(avctx, AV_LOG_ERROR,
-                   "Invalid tile size %dx%d\n", w, h);
+                   "Invalid tile position (%d.%d %d.%d outside %dx%d).\n",
+                   x, y, x2, y2, ctx->width, ctx->height);
             return AVERROR_INVALIDDATA;
         }
+        w = x2 - x;
+        h = y2 - y;
 
         ret = av_reallocp(&ctx->tilebuffer, tile_size);
         if (!ctx->tilebuffer)