Commit f77bfa83 authored by Ronald S. Bultje's avatar Ronald S. Bultje

xxan: protect against chroma LUT overreads.

Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
CC: libav-stable@libav.org
parent 55188278
...@@ -162,7 +162,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off) ...@@ -162,7 +162,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
int i, j; int i, j;
const uint8_t *src, *src_end; const uint8_t *src, *src_end;
const uint8_t *table; const uint8_t *table;
int mode, offset, dec_size; int mode, offset, dec_size, table_size;
if (!chroma_off) if (!chroma_off)
return 0; return 0;
...@@ -171,9 +171,11 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off) ...@@ -171,9 +171,11 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
return -1; return -1;
} }
bytestream2_seek(&s->gb, chroma_off + 4, SEEK_SET); bytestream2_seek(&s->gb, chroma_off + 4, SEEK_SET);
mode = bytestream2_get_le16(&s->gb); mode = bytestream2_get_le16(&s->gb);
table = s->gb.buffer; table = s->gb.buffer;
offset = bytestream2_get_le16(&s->gb) * 2; table_size = bytestream2_get_le16(&s->gb);
offset = table_size * 2;
table_size += 1;
if (offset >= bytestream2_get_bytes_left(&s->gb)) { if (offset >= bytestream2_get_bytes_left(&s->gb)) {
av_log(avctx, AV_LOG_ERROR, "Invalid chroma block offset\n"); av_log(avctx, AV_LOG_ERROR, "Invalid chroma block offset\n");
...@@ -196,7 +198,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off) ...@@ -196,7 +198,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
for (j = 0; j < avctx->height >> 1; j++) { for (j = 0; j < avctx->height >> 1; j++) {
for (i = 0; i < avctx->width >> 1; i++) { for (i = 0; i < avctx->width >> 1; i++) {
val = *src++; val = *src++;
if (val) { if (val && val < table_size) {
val = AV_RL16(table + (val << 1)); val = AV_RL16(table + (val << 1));
uval = (val >> 3) & 0xF8; uval = (val >> 3) & 0xF8;
vval = (val >> 8) & 0xF8; vval = (val >> 8) & 0xF8;
...@@ -216,7 +218,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off) ...@@ -216,7 +218,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
for (j = 0; j < avctx->height >> 2; j++) { for (j = 0; j < avctx->height >> 2; j++) {
for (i = 0; i < avctx->width >> 1; i += 2) { for (i = 0; i < avctx->width >> 1; i += 2) {
val = *src++; val = *src++;
if (val) { if (val && val < table_size) {
val = AV_RL16(table + (val << 1)); val = AV_RL16(table + (val << 1));
uval = (val >> 3) & 0xF8; uval = (val >> 3) & 0xF8;
vval = (val >> 8) & 0xF8; vval = (val >> 8) & 0xF8;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment