avcodec/hnm4video: check offset in decode_interframe_v4() more completely
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 22 Nov 2013 20:00:11 +0000 (21:00 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 22 Nov 2013 21:12:27 +0000 (22:12 +0100)
Fixes out of array reads
Fixes: signal_sigsegv_e74c1e_1092_BROCIME.HNM
Fixes: signal_sigsegv_e74e85_2620_PLAQUE0.HNM

Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libavcodec/hnm4video.c

index b6ab60e..5979926 100644 (file)
@@ -146,7 +146,8 @@ static void decode_interframe_v4(AVCodecContext *avctx, uint8_t *src, uint32_t s
 {
     Hnm4VideoContext *hnm = avctx->priv_data;
     GetByteContext gb;
-    uint32_t writeoffset = 0, count, left, offset;
+    uint32_t writeoffset = 0;
+    int count, left, offset;
     uint8_t tag, previous, backline, backward, swap;
 
     bytestream2_init(&gb, src, size);
@@ -187,10 +188,10 @@ static void decode_interframe_v4(AVCodecContext *avctx, uint8_t *src, uint32_t s
 
             left = count;
 
-            if (!backward && offset + count >= hnm->width * hnm->height) {
+            if (!backward && offset + 2*count > hnm->width * hnm->height) {
                 av_log(avctx, AV_LOG_ERROR, "Attempting to read out of bounds");
                 break;
-            } else if (backward && offset >= hnm->width * hnm->height) {
+            } else if (backward && offset + 1 >= hnm->width * hnm->height) {
                 av_log(avctx, AV_LOG_ERROR, "Attempting to read out of bounds");
                 break;
             } else if (writeoffset + count >= hnm->width * hnm->height) {
@@ -198,6 +199,17 @@ static void decode_interframe_v4(AVCodecContext *avctx, uint8_t *src, uint32_t s
                        "Attempting to write out of bounds");
                 break;
             }
+            if(backward) {
+                if (offset < (!!backline)*(2 * hnm->width - 1) + 2*(left-1)) {
+                    av_log(avctx, AV_LOG_ERROR, "Attempting to read out of bounds\n");
+                    break;
+                }
+            } else {
+                if (offset < (!!backline)*(2 * hnm->width - 1)) {
+                    av_log(avctx, AV_LOG_ERROR, "Attempting to read out of bounds\n");
+                    break;
+                }
+            }
 
             if (previous) {
                 while (left > 0) {