Merge commit 'c8fb5d0f383fcbb0da9bdef609c3a826df0064f7' into release/1.1

* commit 'c8fb5d0f383fcbb0da9bdef609c3a826df0064f7':
  Update Changelog
  indeo: check for reference when inheriting mvs
  indeo: use proper error code
  indeo: Properly forward the error codes
  mjpeg: Check the unescaped size for overflows
  wmapro: error out on impossible scale factor offsets
  wmapro: check the min_samples_per_subframe
  wmapro: return early on unsupported condition
  wmapro: check num_vec_coeffs against the actual available buffer
  wmapro: make sure there is room to store the current packet
  lavc: move put_bits_left in put_bits.h
  4xm: do not overread the source buffer in decode_p_block
  4xm: check bitstream_size boundary before using it

Conflicts:
	Changelog
	libavcodec/4xm.c
	libavcodec/mjpegdec.c
	libavcodec/wmaprodec.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer
2013-08-27 16:06:47 +02:00
7 changed files with 73 additions and 23 deletions

View File

@@ -2,6 +2,17 @@ Entries are sorted chronologically from oldest to youngest within each release,
releases are sorted from youngest to oldest. releases are sorted from youngest to oldest.
version <next>: version <next>:
- indeo: Check for reference when inheriting motion vectors
- indeo: Properly forward the error codes
- mjpeg: Check the unescaped size for overflows
- wmapro: Error out on impossible scale factor offsets
- wmapro: Check the min_samples_per_subframe
- wmapro: Return early on unsupported condition
- wmapro: Check num_vec_coeffs against the actual available buffer
- wmapro: Make sure there is room to store the current packet
- lavc: Move put_bits_left in put_bits.h
- 4xm: Do not overread the source buffer in decode_p_block
- 4xm: Check bitstream_size boundary before using it
Most of the following fixes resulted from test samples that the Google Most of the following fixes resulted from test samples that the Google
Security Team has kindly made available to us: Security Team has kindly made available to us:

View File

@@ -374,6 +374,10 @@ static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
log2w, log2h, stride)) < 0) log2w, log2h, stride)) < 0)
return ret; return ret;
} else if (code == 3 && f->version < 2) { } else if (code == 3 && f->version < 2) {
if (start > src || src > end) {
av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
return AVERROR_INVALIDDATA;
}
mcdc(dst, src, log2w, h, stride, 1, 0); mcdc(dst, src, log2w, h, stride, 1, 0);
} else if (code == 4) { } else if (code == 4) {
if (bytestream2_get_bytes_left(&f->g) < 1) { if (bytestream2_get_bytes_left(&f->g) < 1) {
@@ -395,6 +399,10 @@ static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
if (start > src || src > end) {
av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
return AVERROR_INVALIDDATA;
}
mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16u(&f->g2)); mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16u(&f->g2));
} else if (code == 6) { } else if (code == 6) {
if (bytestream2_get_bytes_left(&f->g2) < 4) { if (bytestream2_get_bytes_left(&f->g2) < 4) {
@@ -757,7 +765,10 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length)
unsigned int prestream_size; unsigned int prestream_size;
const uint8_t *prestream; const uint8_t *prestream;
if (bitstream_size > (1<<26) || length < bitstream_size + 12) { if (bitstream_size > (1 << 26))
return AVERROR_INVALIDDATA;
if (length < bitstream_size + 12) {
av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n"); av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
@@ -766,7 +777,6 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length)
prestream = buf + bitstream_size + 12; prestream = buf + bitstream_size + 12;
if (prestream_size + bitstream_size + 12 != length if (prestream_size + bitstream_size + 12 != length
|| bitstream_size > (1 << 26)
|| prestream_size > (1 << 26)) { || prestream_size > (1 << 26)) {
av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n",
prestream_size, bitstream_size, length); prestream_size, bitstream_size, length);

View File

@@ -350,11 +350,6 @@ static av_cold int dvvideo_init_encoder(AVCodecContext *avctx)
static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5; static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5;
static const int mb_area_start[5] = { 1, 6, 21, 43, 64 }; static const int mb_area_start[5] = { 1, 6, 21, 43, 64 };
static inline int put_bits_left(PutBitContext* s)
{
return (s->buf_end - s->buf) * 8 - put_bits_count(s);
}
#if CONFIG_SMALL #if CONFIG_SMALL
/* Converts run and level (where level != 0) pair into VLC, returning bit size */ /* Converts run and level (where level != 0) pair into VLC, returning bit size */
static av_always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc) static av_always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc)

View File

@@ -85,7 +85,7 @@ static int ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *vlc, int flag)
bits[pos] = i + cb->xbits[i] + not_last_row; bits[pos] = i + cb->xbits[i] + not_last_row;
if (bits[pos] > IVI_VLC_BITS) if (bits[pos] > IVI_VLC_BITS)
return -1; /* invalid descriptor */ return AVERROR_INVALIDDATA; /* invalid descriptor */
codewords[pos] = inv_bits((prefix | j), bits[pos]); codewords[pos] = inv_bits((prefix | j), bits[pos]);
if (!bits[pos]) if (!bits[pos])
@@ -489,7 +489,7 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile
} else { } else {
if (sym >= 256U) { if (sym >= 256U) {
av_log(avctx, AV_LOG_ERROR, "Invalid sym encountered: %d.\n", sym); av_log(avctx, AV_LOG_ERROR, "Invalid sym encountered: %d.\n", sym);
return -1; return AVERROR_INVALIDDATA;
} }
run = rvmap->runtab[sym]; run = rvmap->runtab[sym];
val = rvmap->valtab[sym]; val = rvmap->valtab[sym];
@@ -512,7 +512,7 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile
}// while }// while
if (scan_pos >= num_coeffs && sym != rvmap->eob_sym) if (scan_pos >= num_coeffs && sym != rvmap->eob_sym)
return -1; /* corrupt block data */ return AVERROR_INVALIDDATA; /* corrupt block data */
/* undoing DC coeff prediction for intra-blocks */ /* undoing DC coeff prediction for intra-blocks */
if (is_intra && band->is_2d_trans) { if (is_intra && band->is_2d_trans) {
@@ -804,8 +804,16 @@ static int decode_band(IVI45DecContext *ctx,
break; break;
result = ivi_decode_blocks(&ctx->gb, band, tile, avctx); result = ivi_decode_blocks(&ctx->gb, band, tile, avctx);
if (result < 0 || ((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) { if (result < 0) {
av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n"); av_log(avctx, AV_LOG_ERROR,
"Corrupted tile data encountered!\n");
break;
}
if (((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) {
av_log(avctx, AV_LOG_ERROR,
"Tile data_size mismatch!\n");
result = AVERROR_INVALIDDATA;
break; break;
} }
@@ -857,14 +865,14 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
if (result) { if (result) {
av_log(avctx, AV_LOG_ERROR, av_log(avctx, AV_LOG_ERROR,
"Error while decoding picture header: %d\n", result); "Error while decoding picture header: %d\n", result);
return -1; return result;
} }
if (ctx->gop_invalid) if (ctx->gop_invalid)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
if (ctx->gop_flags & IVI5_IS_PROTECTED) { if (ctx->gop_flags & IVI5_IS_PROTECTED) {
av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n"); av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n");
return -1; return AVERROR_PATCHWELCOME;
} }
ctx->switch_buffers(ctx); ctx->switch_buffers(ctx);
@@ -876,10 +884,10 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
for (p = 0; p < 3; p++) { for (p = 0; p < 3; p++) {
for (b = 0; b < ctx->planes[p].num_bands; b++) { for (b = 0; b < ctx->planes[p].num_bands; b++) {
result = decode_band(ctx, &ctx->planes[p].bands[b], avctx); result = decode_band(ctx, &ctx->planes[p].bands[b], avctx);
if (result) { if (result < 0) {
av_log(avctx, AV_LOG_ERROR, av_log(avctx, AV_LOG_ERROR,
"Error while decoding band: %d, plane: %d\n", b, p); "Error while decoding band: %d, plane: %d\n", b, p);
return -1; return result;
} }
} }
} }

View File

@@ -1655,15 +1655,20 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
/* EOF */ /* EOF */
if (start_code < 0) { if (start_code < 0) {
goto the_end; goto the_end;
} else if (unescaped_buf_size > (1U<<28)) { } else if (unescaped_buf_size > INT_MAX / 8) {
av_log(avctx, AV_LOG_ERROR, "MJPEG packet 0x%x too big (0x%x/0x%x), corrupt data?\n", av_log(avctx, AV_LOG_ERROR,
"MJPEG packet 0x%x too big (%d/%d), corrupt data?\n",
start_code, unescaped_buf_size, buf_size); start_code, unescaped_buf_size, buf_size);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} else { } else {
av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n", av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n",
start_code, buf_end - buf_ptr); start_code, buf_end - buf_ptr);
init_get_bits(&s->gb, unescaped_buf_ptr, unescaped_buf_size * 8); ret = init_get_bits(&s->gb, unescaped_buf_ptr,
unescaped_buf_size * 8);
if (ret < 0)
return ret;
s->start_code = start_code; s->start_code = start_code;
if (s->avctx->debug & FF_DEBUG_STARTCODE) if (s->avctx->debug & FF_DEBUG_STARTCODE)

View File

@@ -73,6 +73,14 @@ static inline int put_bits_count(PutBitContext *s)
return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left; return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left;
} }
/**
* @return the number of bits available in the bitstream.
*/
static inline int put_bits_left(PutBitContext* s)
{
return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left;
}
/** /**
* Pad the end of the output stream with zeros. * Pad the end of the output stream with zeros.
*/ */

View File

@@ -107,6 +107,7 @@
#define WMAPRO_BLOCK_MIN_BITS 6 ///< log2 of min block size #define WMAPRO_BLOCK_MIN_BITS 6 ///< log2 of min block size
#define WMAPRO_BLOCK_MAX_BITS 13 ///< log2 of max block size #define WMAPRO_BLOCK_MAX_BITS 13 ///< log2 of max block size
#define WMAPRO_BLOCK_MIN_SIZE (1 << WMAPRO_BLOCK_MIN_BITS) ///< minimum block size
#define WMAPRO_BLOCK_MAX_SIZE (1 << WMAPRO_BLOCK_MAX_BITS) ///< maximum block size #define WMAPRO_BLOCK_MAX_SIZE (1 << WMAPRO_BLOCK_MAX_BITS) ///< maximum block size
#define WMAPRO_BLOCK_SIZES (WMAPRO_BLOCK_MAX_BITS - WMAPRO_BLOCK_MIN_BITS + 1) ///< possible block sizes #define WMAPRO_BLOCK_SIZES (WMAPRO_BLOCK_MAX_BITS - WMAPRO_BLOCK_MIN_BITS + 1) ///< possible block sizes
@@ -340,7 +341,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
if (s->min_samples_per_subframe < (1<<WMAPRO_BLOCK_MIN_BITS)) { if (s->min_samples_per_subframe < WMAPRO_BLOCK_MIN_SIZE) {
av_log(avctx, AV_LOG_ERROR, "min_samples_per_subframe of %d too small\n", av_log(avctx, AV_LOG_ERROR, "min_samples_per_subframe of %d too small\n",
s->min_samples_per_subframe); s->min_samples_per_subframe);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
@@ -442,7 +443,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
for (x = 0; x < num_possible_block_sizes; x++) { for (x = 0; x < num_possible_block_sizes; x++) {
int v = 0; int v = 0;
while (s->sfb_offsets[x][v + 1] << x < offset) while (s->sfb_offsets[x][v + 1] << x < offset)
++v; if (++v >= MAX_BANDS)
return AVERROR_INVALIDDATA;
s->sf_offsets[i][x][b] = v; s->sf_offsets[i][x][b] = v;
} }
} }
@@ -732,6 +734,7 @@ static int decode_channel_transform(WMAProDecodeCtx* s)
if (get_bits1(&s->gb)) { if (get_bits1(&s->gb)) {
av_log_ask_for_sample(s->avctx, av_log_ask_for_sample(s->avctx,
"unsupported channel transform type\n"); "unsupported channel transform type\n");
return AVERROR_PATCHWELCOME;
} }
} else { } else {
chgroup->transform = 1; chgroup->transform = 1;
@@ -1134,11 +1137,12 @@ static int decode_subframe(WMAProDecodeCtx *s)
cur_subwoofer_cutoff = s->subwoofer_cutoffs[s->table_idx]; cur_subwoofer_cutoff = s->subwoofer_cutoffs[s->table_idx];
/** configure the decoder for the current subframe */ /** configure the decoder for the current subframe */
offset += s->samples_per_frame >> 1;
for (i = 0; i < s->channels_for_cur_subframe; i++) { for (i = 0; i < s->channels_for_cur_subframe; i++) {
int c = s->channel_indexes_for_cur_subframe[i]; int c = s->channel_indexes_for_cur_subframe[i];
s->channel[c].coeffs = &s->channel[c].out[(s->samples_per_frame >> 1) s->channel[c].coeffs = &s->channel[c].out[offset];
+ offset];
} }
s->subframe_len = subframe_len; s->subframe_len = subframe_len;
@@ -1194,6 +1198,7 @@ static int decode_subframe(WMAProDecodeCtx *s)
av_log(s->avctx, AV_LOG_ERROR, "num_vec_coeffs %d is too large\n", num_vec_coeffs); av_log(s->avctx, AV_LOG_ERROR, "num_vec_coeffs %d is too large\n", num_vec_coeffs);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
av_assert0(num_vec_coeffs + offset <= FF_ARRAY_ELEMS(s->channel[c].out));
s->channel[c].num_vec_coeffs = num_vec_coeffs; s->channel[c].num_vec_coeffs = num_vec_coeffs;
} }
} else { } else {
@@ -1475,6 +1480,14 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len,
return; return;
} }
if (len > put_bits_left(&s->pb)) {
av_log(s->avctx, AV_LOG_ERROR,
"Cannot append %d bits, only %d bits available.\n",
len, put_bits_left(&s->pb));
s->packet_loss = 1;
return;
}
s->num_saved_bits += len; s->num_saved_bits += len;
if (!append) { if (!append) {
avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3),