mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-12-08 06:09:50 +00:00
avcodec/exr: Check rle_raw_data and surroundings
Fixes: out of array read Fixes: BIGSLEEP-436510153/dwa_uncompress_read.exr Found-by: Google Big Sleep Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
parent
8173ae547a
commit
0d9c003d76
1 changed files with 13 additions and 2 deletions
|
|
@ -996,6 +996,7 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
|
||||||
const int dc_h = td->ysize >> 3;
|
const int dc_h = td->ysize >> 3;
|
||||||
GetByteContext gb, agb;
|
GetByteContext gb, agb;
|
||||||
int skip, ret;
|
int skip, ret;
|
||||||
|
int have_rle = 0;
|
||||||
|
|
||||||
if (compressed_size <= 88)
|
if (compressed_size <= 88)
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
@ -1020,6 +1021,11 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
|
||||||
)
|
)
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
|
if ((uint64_t)rle_raw_size > INT_MAX) {
|
||||||
|
avpriv_request_sample(s->avctx, "Too big rle_raw_size");
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
bytestream2_init(&gb, src + 88, compressed_size - 88);
|
bytestream2_init(&gb, src + 88, compressed_size - 88);
|
||||||
skip = bytestream2_get_le16(&gb);
|
skip = bytestream2_get_le16(&gb);
|
||||||
if (skip < 2)
|
if (skip < 2)
|
||||||
|
|
@ -1090,6 +1096,9 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
|
||||||
if (rle_raw_size > 0 && rle_csize > 0 && rle_usize > 0) {
|
if (rle_raw_size > 0 && rle_csize > 0 && rle_usize > 0) {
|
||||||
unsigned long dest_len = rle_usize;
|
unsigned long dest_len = rle_usize;
|
||||||
|
|
||||||
|
if (2LL * td->xsize * td->ysize > rle_raw_size)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
av_fast_padded_malloc(&td->rle_data, &td->rle_size, rle_usize);
|
av_fast_padded_malloc(&td->rle_data, &td->rle_size, rle_usize);
|
||||||
if (!td->rle_data)
|
if (!td->rle_data)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
@ -1106,6 +1115,8 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
bytestream2_skip(&gb, rle_csize);
|
bytestream2_skip(&gb, rle_csize);
|
||||||
|
|
||||||
|
have_rle = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytestream2_init(&agb, td->ac_data, ac_count * 2);
|
bytestream2_init(&agb, td->ac_data, ac_count * 2);
|
||||||
|
|
@ -1187,7 +1198,7 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (s->pixel_type == EXR_HALF) {
|
if (s->pixel_type == EXR_HALF) {
|
||||||
for (int y = 0; y < td->ysize && td->rle_raw_data; y++) {
|
for (int y = 0; y < td->ysize && have_rle; y++) {
|
||||||
uint16_t *ao = ((uint16_t *)td->uncompressed_data) + y * td->xsize * s->nb_channels;
|
uint16_t *ao = ((uint16_t *)td->uncompressed_data) + y * td->xsize * s->nb_channels;
|
||||||
uint8_t *ai0 = td->rle_raw_data + y * td->xsize;
|
uint8_t *ai0 = td->rle_raw_data + y * td->xsize;
|
||||||
uint8_t *ai1 = td->rle_raw_data + y * td->xsize + rle_raw_size / 2;
|
uint8_t *ai1 = td->rle_raw_data + y * td->xsize + rle_raw_size / 2;
|
||||||
|
|
@ -1196,7 +1207,7 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
|
||||||
ao[x] = ai0[x] | (ai1[x] << 8);
|
ao[x] = ai0[x] | (ai1[x] << 8);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int y = 0; y < td->ysize && td->rle_raw_data; y++) {
|
for (int y = 0; y < td->ysize && have_rle; y++) {
|
||||||
uint32_t *ao = ((uint32_t *)td->uncompressed_data) + y * td->xsize * s->nb_channels;
|
uint32_t *ao = ((uint32_t *)td->uncompressed_data) + y * td->xsize * s->nb_channels;
|
||||||
uint8_t *ai0 = td->rle_raw_data + y * td->xsize;
|
uint8_t *ai0 = td->rle_raw_data + y * td->xsize;
|
||||||
uint8_t *ai1 = td->rle_raw_data + y * td->xsize + rle_raw_size / 2;
|
uint8_t *ai1 = td->rle_raw_data + y * td->xsize + rle_raw_size / 2;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue