mirror of
				https://github.com/nyanmisaka/ffmpeg-rockchip.git
				synced 2025-10-25 09:51:06 +08:00 
			
		
		
		
	avcodec/msrledec: restructure msrle_decode_pal4() based on the line number instead of the pixel pointer
Fixes out of array access Fixes: da14e86d8462be6493eab16bc2d40f88/asan_heap-oob_204cfd2_528_cov_340150052_COMPRESS.BMP Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
		| @@ -37,16 +37,14 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, | |||||||
|     unsigned char extra_byte, odd_pixel; |     unsigned char extra_byte, odd_pixel; | ||||||
|     unsigned char stream_byte; |     unsigned char stream_byte; | ||||||
|     unsigned int pixel_ptr = 0; |     unsigned int pixel_ptr = 0; | ||||||
|     int row_dec = pic->linesize[0]; |     int line = avctx->height - 1; | ||||||
|     int row_ptr = (avctx->height - 1) * row_dec; |  | ||||||
|     int frame_size = row_dec * avctx->height; |  | ||||||
|     int i; |     int i; | ||||||
|  |  | ||||||
|     while (row_ptr >= 0) { |     while (line >= 0 && pixel_ptr <= avctx->width) { | ||||||
|         if (bytestream2_get_bytes_left(gb) <= 0) { |         if (bytestream2_get_bytes_left(gb) <= 0) { | ||||||
|             av_log(avctx, AV_LOG_ERROR, |             av_log(avctx, AV_LOG_ERROR, | ||||||
|                    "MS RLE: bytestream overrun, %d rows left\n", |                    "MS RLE: bytestream overrun, %dx%d left\n", | ||||||
|                    row_ptr); |                    avctx->width - pixel_ptr, line); | ||||||
|             return AVERROR_INVALIDDATA; |             return AVERROR_INVALIDDATA; | ||||||
|         } |         } | ||||||
|         rle_code = stream_byte = bytestream2_get_byteu(gb); |         rle_code = stream_byte = bytestream2_get_byteu(gb); | ||||||
| @@ -55,7 +53,7 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, | |||||||
|             stream_byte = bytestream2_get_byte(gb); |             stream_byte = bytestream2_get_byte(gb); | ||||||
|             if (stream_byte == 0) { |             if (stream_byte == 0) { | ||||||
|                 /* line is done, goto the next one */ |                 /* line is done, goto the next one */ | ||||||
|                 row_ptr -= row_dec; |                 line--; | ||||||
|                 pixel_ptr = 0; |                 pixel_ptr = 0; | ||||||
|             } else if (stream_byte == 1) { |             } else if (stream_byte == 1) { | ||||||
|                 /* decode is done */ |                 /* decode is done */ | ||||||
| @@ -65,13 +63,12 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, | |||||||
|                 stream_byte = bytestream2_get_byte(gb); |                 stream_byte = bytestream2_get_byte(gb); | ||||||
|                 pixel_ptr += stream_byte; |                 pixel_ptr += stream_byte; | ||||||
|                 stream_byte = bytestream2_get_byte(gb); |                 stream_byte = bytestream2_get_byte(gb); | ||||||
|                 row_ptr -= stream_byte * row_dec; |  | ||||||
|             } else { |             } else { | ||||||
|                 // copy pixels from encoded stream |                 // copy pixels from encoded stream | ||||||
|                 odd_pixel =  stream_byte & 1; |                 odd_pixel =  stream_byte & 1; | ||||||
|                 rle_code = (stream_byte + 1) / 2; |                 rle_code = (stream_byte + 1) / 2; | ||||||
|                 extra_byte = rle_code & 0x01; |                 extra_byte = rle_code & 0x01; | ||||||
|                 if (row_ptr + pixel_ptr + stream_byte > frame_size || |                 if (pixel_ptr + 2*rle_code - odd_pixel > avctx->width || | ||||||
|                     bytestream2_get_bytes_left(gb) < rle_code) { |                     bytestream2_get_bytes_left(gb) < rle_code) { | ||||||
|                     av_log(avctx, AV_LOG_ERROR, |                     av_log(avctx, AV_LOG_ERROR, | ||||||
|                            "MS RLE: frame/stream ptr just went out of bounds (copy)\n"); |                            "MS RLE: frame/stream ptr just went out of bounds (copy)\n"); | ||||||
| @@ -82,13 +79,13 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, | |||||||
|                     if (pixel_ptr >= avctx->width) |                     if (pixel_ptr >= avctx->width) | ||||||
|                         break; |                         break; | ||||||
|                     stream_byte = bytestream2_get_byteu(gb); |                     stream_byte = bytestream2_get_byteu(gb); | ||||||
|                     pic->data[0][row_ptr + pixel_ptr] = stream_byte >> 4; |                     pic->data[0][line * pic->linesize[0] + pixel_ptr] = stream_byte >> 4; | ||||||
|                     pixel_ptr++; |                     pixel_ptr++; | ||||||
|                     if (i + 1 == rle_code && odd_pixel) |                     if (i + 1 == rle_code && odd_pixel) | ||||||
|                         break; |                         break; | ||||||
|                     if (pixel_ptr >= avctx->width) |                     if (pixel_ptr >= avctx->width) | ||||||
|                         break; |                         break; | ||||||
|                     pic->data[0][row_ptr + pixel_ptr] = stream_byte & 0x0F; |                     pic->data[0][line * pic->linesize[0] + pixel_ptr] = stream_byte & 0x0F; | ||||||
|                     pixel_ptr++; |                     pixel_ptr++; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
| @@ -98,7 +95,7 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, | |||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             // decode a run of data |             // decode a run of data | ||||||
|             if (row_ptr + pixel_ptr + stream_byte > frame_size) { |             if (pixel_ptr + rle_code > avctx->width + 1) { | ||||||
|                 av_log(avctx, AV_LOG_ERROR, |                 av_log(avctx, AV_LOG_ERROR, | ||||||
|                        "MS RLE: frame ptr just went out of bounds (run)\n"); |                        "MS RLE: frame ptr just went out of bounds (run)\n"); | ||||||
|                 return AVERROR_INVALIDDATA; |                 return AVERROR_INVALIDDATA; | ||||||
| @@ -108,9 +105,9 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, | |||||||
|                 if (pixel_ptr >= avctx->width) |                 if (pixel_ptr >= avctx->width) | ||||||
|                     break; |                     break; | ||||||
|                 if ((i & 1) == 0) |                 if ((i & 1) == 0) | ||||||
|                     pic->data[0][row_ptr + pixel_ptr] = stream_byte >> 4; |                     pic->data[0][line * pic->linesize[0] + pixel_ptr] = stream_byte >> 4; | ||||||
|                 else |                 else | ||||||
|                     pic->data[0][row_ptr + pixel_ptr] = stream_byte & 0x0F; |                     pic->data[0][line * pic->linesize[0] + pixel_ptr] = stream_byte & 0x0F; | ||||||
|                 pixel_ptr++; |                 pixel_ptr++; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Michael Niedermayer
					Michael Niedermayer