From 5a08ba5381cf8d46034440163e71cd95748beceb Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 22 Nov 2013 21:00:11 +0100 Subject: [PATCH] avcodec/hnm4video: check offset in decode_interframe_v4() more completely 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 --- libavcodec/hnm4video.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/libavcodec/hnm4video.c b/libavcodec/hnm4video.c index b6ab60e2ae..5979926fb4 100644 --- a/libavcodec/hnm4video.c +++ b/libavcodec/hnm4video.c @@ -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) {