diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-08-27 16:06:47 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-08-27 16:11:44 +0200 |
commit | 847d3225a8f9e3910d21915db52c3b38986a3fa9 (patch) | |
tree | 2113106109b137eb54665cde6f01db7829d11f9d | |
parent | 465742bbbec4e875b2dae21f8f2e3092113f589c (diff) | |
parent | c8fb5d0f383fcbb0da9bdef609c3a826df0064f7 (diff) | |
download | ffmpeg-847d3225a8f9e3910d21915db52c3b38986a3fa9.tar.gz |
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>
-rw-r--r-- | Changelog | 11 | ||||
-rw-r--r-- | libavcodec/4xm.c | 14 | ||||
-rw-r--r-- | libavcodec/dv.c | 5 | ||||
-rw-r--r-- | libavcodec/ivi_common.c | 26 | ||||
-rw-r--r-- | libavcodec/mjpegdec.c | 11 | ||||
-rw-r--r-- | libavcodec/put_bits.h | 8 | ||||
-rw-r--r-- | libavcodec/wmaprodec.c | 21 |
7 files changed, 73 insertions, 23 deletions
@@ -2,6 +2,17 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. 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 Security Team has kindly made available to us: diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index b174e2ab03..fa663a7659 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -374,6 +374,10 @@ static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, log2w, log2h, stride)) < 0) return ret; } 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); } else if (code == 4) { 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"); 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)); } else if (code == 6) { 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; 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"); 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; if (prestream_size + bitstream_size + 12 != length - || bitstream_size > (1 << 26) || prestream_size > (1 << 26)) { av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length); diff --git a/libavcodec/dv.c b/libavcodec/dv.c index 18c90c2b6c..f8848f213c 100644 --- a/libavcodec/dv.c +++ b/libavcodec/dv.c @@ -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 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 /* 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) diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index 21954ec5a4..afcbe07c25 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -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; if (bits[pos] > IVI_VLC_BITS) - return -1; /* invalid descriptor */ + return AVERROR_INVALIDDATA; /* invalid descriptor */ codewords[pos] = inv_bits((prefix | j), bits[pos]); if (!bits[pos]) @@ -489,7 +489,7 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile } else { if (sym >= 256U) { av_log(avctx, AV_LOG_ERROR, "Invalid sym encountered: %d.\n", sym); - return -1; + return AVERROR_INVALIDDATA; } run = rvmap->runtab[sym]; val = rvmap->valtab[sym]; @@ -512,7 +512,7 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile }// while 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 */ if (is_intra && band->is_2d_trans) { @@ -804,8 +804,16 @@ static int decode_band(IVI45DecContext *ctx, break; result = ivi_decode_blocks(&ctx->gb, band, tile, avctx); - if (result < 0 || ((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) { - av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n"); + if (result < 0) { + 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; } @@ -857,14 +865,14 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (result) { av_log(avctx, AV_LOG_ERROR, "Error while decoding picture header: %d\n", result); - return -1; + return result; } if (ctx->gop_invalid) return AVERROR_INVALIDDATA; if (ctx->gop_flags & IVI5_IS_PROTECTED) { av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n"); - return -1; + return AVERROR_PATCHWELCOME; } 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 (b = 0; b < ctx->planes[p].num_bands; b++) { result = decode_band(ctx, &ctx->planes[p].bands[b], avctx); - if (result) { + if (result < 0) { av_log(avctx, AV_LOG_ERROR, "Error while decoding band: %d, plane: %d\n", b, p); - return -1; + return result; } } } diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 0a701bc395..d377827c09 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1655,15 +1655,20 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, /* EOF */ if (start_code < 0) { goto the_end; - } else if (unescaped_buf_size > (1U<<28)) { - av_log(avctx, AV_LOG_ERROR, "MJPEG packet 0x%x too big (0x%x/0x%x), corrupt data?\n", + } else if (unescaped_buf_size > INT_MAX / 8) { + av_log(avctx, AV_LOG_ERROR, + "MJPEG packet 0x%x too big (%d/%d), corrupt data?\n", start_code, unescaped_buf_size, buf_size); return AVERROR_INVALIDDATA; } else { av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n", 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; if (s->avctx->debug & FF_DEBUG_STARTCODE) diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h index f02965e300..711f58099c 100644 --- a/libavcodec/put_bits.h +++ b/libavcodec/put_bits.h @@ -74,6 +74,14 @@ static inline int put_bits_count(PutBitContext *s) } /** + * @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. */ static inline void flush_put_bits(PutBitContext *s) diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index f6a11e3e14..0878b5f33d 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -107,6 +107,7 @@ #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_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_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; } - 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", s->min_samples_per_subframe); return AVERROR_INVALIDDATA; @@ -442,7 +443,8 @@ static av_cold int decode_init(AVCodecContext *avctx) for (x = 0; x < num_possible_block_sizes; x++) { int v = 0; while (s->sfb_offsets[x][v + 1] << x < offset) - ++v; + if (++v >= MAX_BANDS) + return AVERROR_INVALIDDATA; s->sf_offsets[i][x][b] = v; } } @@ -732,6 +734,7 @@ static int decode_channel_transform(WMAProDecodeCtx* s) if (get_bits1(&s->gb)) { av_log_ask_for_sample(s->avctx, "unsupported channel transform type\n"); + return AVERROR_PATCHWELCOME; } } else { chgroup->transform = 1; @@ -1134,11 +1137,12 @@ static int decode_subframe(WMAProDecodeCtx *s) cur_subwoofer_cutoff = s->subwoofer_cutoffs[s->table_idx]; /** configure the decoder for the current subframe */ + offset += s->samples_per_frame >> 1; + for (i = 0; i < s->channels_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) - + offset]; + s->channel[c].coeffs = &s->channel[c].out[offset]; } 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); 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; } } else { @@ -1475,6 +1480,14 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len, 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; if (!append) { avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), |