mirror of
				https://github.com/nyanmisaka/ffmpeg-rockchip.git
				synced 2025-10-31 12:36:41 +08:00 
			
		
		
		
	avcodec/h2645: Fix NAL unit padding
The parser changes have lost the support for the needed padding, this adds it back Fixes out of array reads Fixes: 03ea21d271abc8acf428d42ace51d8b4/asan_heap-oob_3358eef_5692_16f0cc01ab5225e9ce591659e5c20e35.mkv Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
		| @@ -30,10 +30,11 @@ | |||||||
| #include "h2645_parse.h" | #include "h2645_parse.h" | ||||||
|  |  | ||||||
| int ff_h2645_extract_rbsp(const uint8_t *src, int length, | int ff_h2645_extract_rbsp(const uint8_t *src, int length, | ||||||
|                           H2645NAL *nal) |                           H2645NAL *nal, int small_padding) | ||||||
| { | { | ||||||
|     int i, si, di; |     int i, si, di; | ||||||
|     uint8_t *dst; |     uint8_t *dst; | ||||||
|  |     int64_t padding = small_padding ? AV_INPUT_BUFFER_PADDING_SIZE : MAX_MBPAIR_SIZE; | ||||||
|  |  | ||||||
|     nal->skipped_bytes = 0; |     nal->skipped_bytes = 0; | ||||||
| #define STARTCODE_TEST                                                  \ | #define STARTCODE_TEST                                                  \ | ||||||
| @@ -81,7 +82,7 @@ int ff_h2645_extract_rbsp(const uint8_t *src, int length, | |||||||
|     } |     } | ||||||
| #endif /* HAVE_FAST_UNALIGNED */ | #endif /* HAVE_FAST_UNALIGNED */ | ||||||
|  |  | ||||||
|     if (i >= length - 1) { // no escaped 0 |     if (i >= length - 1 && small_padding) { // no escaped 0 | ||||||
|         nal->data     = |         nal->data     = | ||||||
|         nal->raw_data = src; |         nal->raw_data = src; | ||||||
|         nal->size     = |         nal->size     = | ||||||
| @@ -90,7 +91,7 @@ int ff_h2645_extract_rbsp(const uint8_t *src, int length, | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     av_fast_malloc(&nal->rbsp_buffer, &nal->rbsp_buffer_size, |     av_fast_malloc(&nal->rbsp_buffer, &nal->rbsp_buffer_size, | ||||||
|                    length + AV_INPUT_BUFFER_PADDING_SIZE); |                    length + padding); | ||||||
|     if (!nal->rbsp_buffer) |     if (!nal->rbsp_buffer) | ||||||
|         return AVERROR(ENOMEM); |         return AVERROR(ENOMEM); | ||||||
|  |  | ||||||
| @@ -247,7 +248,7 @@ static int h264_parse_nal_header(H2645NAL *nal, void *logctx) | |||||||
|  |  | ||||||
| int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, | int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, | ||||||
|                           void *logctx, int is_nalff, int nal_length_size, |                           void *logctx, int is_nalff, int nal_length_size, | ||||||
|                           enum AVCodecID codec_id) |                           enum AVCodecID codec_id, int small_padding) | ||||||
| { | { | ||||||
|     int consumed, ret = 0; |     int consumed, ret = 0; | ||||||
|     const uint8_t *next_avc = is_nalff ? buf : buf + length; |     const uint8_t *next_avc = is_nalff ? buf : buf + length; | ||||||
| @@ -325,7 +326,7 @@ int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, | |||||||
|         } |         } | ||||||
|         nal = &pkt->nals[pkt->nb_nals]; |         nal = &pkt->nals[pkt->nb_nals]; | ||||||
|  |  | ||||||
|         consumed = ff_h2645_extract_rbsp(buf, extract_length, nal); |         consumed = ff_h2645_extract_rbsp(buf, extract_length, nal, small_padding); | ||||||
|         if (consumed < 0) |         if (consumed < 0) | ||||||
|             return consumed; |             return consumed; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,6 +26,8 @@ | |||||||
| #include "avcodec.h" | #include "avcodec.h" | ||||||
| #include "get_bits.h" | #include "get_bits.h" | ||||||
|  |  | ||||||
|  | #define MAX_MBPAIR_SIZE (256*1024) // a tighter bound could be calculated if someone cares about a few bytes | ||||||
|  |  | ||||||
| typedef struct H2645NAL { | typedef struct H2645NAL { | ||||||
|     uint8_t *rbsp_buffer; |     uint8_t *rbsp_buffer; | ||||||
|     int rbsp_buffer_size; |     int rbsp_buffer_size; | ||||||
| @@ -74,14 +76,14 @@ typedef struct H2645Packet { | |||||||
|  * Extract the raw (unescaped) bitstream. |  * Extract the raw (unescaped) bitstream. | ||||||
|  */ |  */ | ||||||
| int ff_h2645_extract_rbsp(const uint8_t *src, int length, | int ff_h2645_extract_rbsp(const uint8_t *src, int length, | ||||||
|                           H2645NAL *nal); |                           H2645NAL *nal, int small_padding); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Split an input packet into NAL units. |  * Split an input packet into NAL units. | ||||||
|  */ |  */ | ||||||
| int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, | int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, | ||||||
|                           void *logctx, int is_nalff, int nal_length_size, |                           void *logctx, int is_nalff, int nal_length_size, | ||||||
|                           enum AVCodecID codec_id); |                           enum AVCodecID codec_id, int small_padding); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Free all the allocated memory in the packet. |  * Free all the allocated memory in the packet. | ||||||
|   | |||||||
| @@ -337,7 +337,7 @@ static int decode_extradata_ps(const uint8_t *data, int size, H264ParamSets *ps, | |||||||
|     H2645Packet pkt = { 0 }; |     H2645Packet pkt = { 0 }; | ||||||
|     int i, ret = 0; |     int i, ret = 0; | ||||||
|  |  | ||||||
|     ret = ff_h2645_packet_split(&pkt, data, size, logctx, is_avc, 2, AV_CODEC_ID_H264); |     ret = ff_h2645_packet_split(&pkt, data, size, logctx, is_avc, 2, AV_CODEC_ID_H264, 1); | ||||||
|     if (ret < 0) { |     if (ret < 0) { | ||||||
|         ret = 0; |         ret = 0; | ||||||
|         goto fail; |         goto fail; | ||||||
|   | |||||||
| @@ -318,7 +318,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, | |||||||
|             } |             } | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         consumed = ff_h2645_extract_rbsp(buf + buf_index, src_length, &nal); |         consumed = ff_h2645_extract_rbsp(buf + buf_index, src_length, &nal, 1); | ||||||
|         if (consumed < 0) |         if (consumed < 0) | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -748,7 +748,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size) | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     ret = ff_h2645_packet_split(&h->pkt, buf, buf_size, avctx, h->is_avc, |     ret = ff_h2645_packet_split(&h->pkt, buf, buf_size, avctx, h->is_avc, | ||||||
|                                 h->nal_length_size, avctx->codec_id); |                                 h->nal_length_size, avctx->codec_id, avctx->flags2 & AV_CODEC_FLAG2_FAST); | ||||||
|     if (ret < 0) { |     if (ret < 0) { | ||||||
|         av_log(avctx, AV_LOG_ERROR, |         av_log(avctx, AV_LOG_ERROR, | ||||||
|                "Error splitting the input into NAL units.\n"); |                "Error splitting the input into NAL units.\n"); | ||||||
|   | |||||||
| @@ -55,8 +55,6 @@ | |||||||
|  |  | ||||||
| #define MAX_DELAYED_PIC_COUNT  16 | #define MAX_DELAYED_PIC_COUNT  16 | ||||||
|  |  | ||||||
| #define MAX_MBPAIR_SIZE (256*1024) // a tighter bound could be calculated if someone cares about a few bytes |  | ||||||
|  |  | ||||||
| /* Compiling in interlaced support reduces the speed | /* Compiling in interlaced support reduces the speed | ||||||
|  * of progressive decoding by about 2%. */ |  * of progressive decoding by about 2%. */ | ||||||
| #define ALLOW_INTERLACE | #define ALLOW_INTERLACE | ||||||
|   | |||||||
| @@ -2867,7 +2867,7 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) | |||||||
|     /* split the input packet into NAL units, so we know the upper bound on the |     /* split the input packet into NAL units, so we know the upper bound on the | ||||||
|      * number of slices in the frame */ |      * number of slices in the frame */ | ||||||
|     ret = ff_h2645_packet_split(&s->pkt, buf, length, s->avctx, s->is_nalff, |     ret = ff_h2645_packet_split(&s->pkt, buf, length, s->avctx, s->is_nalff, | ||||||
|                                 s->nal_length_size, s->avctx->codec_id); |                                 s->nal_length_size, s->avctx->codec_id, 1); | ||||||
|     if (ret < 0) { |     if (ret < 0) { | ||||||
|         av_log(s->avctx, AV_LOG_ERROR, |         av_log(s->avctx, AV_LOG_ERROR, | ||||||
|                "Error splitting the input into NAL units.\n"); |                "Error splitting the input into NAL units.\n"); | ||||||
|   | |||||||
| @@ -90,7 +90,7 @@ static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, | |||||||
|     int ret, i; |     int ret, i; | ||||||
|  |  | ||||||
|     ret = ff_h2645_packet_split(&ctx->pkt, buf, buf_size, avctx, 0, 0, |     ret = ff_h2645_packet_split(&ctx->pkt, buf, buf_size, avctx, 0, 0, | ||||||
|                                 AV_CODEC_ID_HEVC); |                                 AV_CODEC_ID_HEVC, 1); | ||||||
|     if (ret < 0) |     if (ret < 0) | ||||||
|         return ret; |         return ret; | ||||||
|  |  | ||||||
| @@ -243,7 +243,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, | |||||||
|                 src_length = 20; |                 src_length = 20; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         consumed = ff_h2645_extract_rbsp(buf, src_length, nal); |         consumed = ff_h2645_extract_rbsp(buf, src_length, nal, 1); | ||||||
|         if (consumed < 0) |         if (consumed < 0) | ||||||
|             return consumed; |             return consumed; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -69,7 +69,7 @@ static int generate_fake_vps(QSVEncContext *q, AVCodecContext *avctx) | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /* parse the SPS */ |     /* parse the SPS */ | ||||||
|     ret = ff_h2645_extract_rbsp(avctx->extradata + 4, avctx->extradata_size - 4, &sps_nal); |     ret = ff_h2645_extract_rbsp(avctx->extradata + 4, avctx->extradata_size - 4, &sps_nal, 1); | ||||||
|     if (ret < 0) { |     if (ret < 0) { | ||||||
|         av_log(avctx, AV_LOG_ERROR, "Error unescaping the SPS buffer\n"); |         av_log(avctx, AV_LOG_ERROR, "Error unescaping the SPS buffer\n"); | ||||||
|         return ret; |         return ret; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Michael Niedermayer
					Michael Niedermayer