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:
		
							parent
							
								
									e2a39b103e
								
							
						
					
					
						commit
						cc13bc8c4f
					
				@ -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;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user