avformat/rtpenc_vc2hq: Check sizes

Fixes: CID1452585 Untrusted loop bound

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
Michael Niedermayer 2024-06-08 10:17:42 +02:00 committed by Paul B Mahol
parent 9d44b3bd70
commit 9bd862bcb4

View File

@ -45,7 +45,7 @@ static void send_packet(AVFormatContext *ctx, uint8_t parse_code, int info_hdr_s
ff_rtp_send_data(ctx, rtp_ctx->buf, RTP_VC2HQ_PL_HEADER_SIZE + info_hdr_size + size, rtp_m); ff_rtp_send_data(ctx, rtp_ctx->buf, RTP_VC2HQ_PL_HEADER_SIZE + info_hdr_size + size, rtp_m);
} }
static void send_picture(AVFormatContext *ctx, const uint8_t *buf, int size, int interlaced) static int send_picture(AVFormatContext *ctx, const uint8_t *buf, int size, int interlaced)
{ {
RTPMuxContext *rtp_ctx = ctx->priv_data; RTPMuxContext *rtp_ctx = ctx->priv_data;
GetBitContext gc; GetBitContext gc;
@ -54,6 +54,9 @@ static void send_picture(AVFormatContext *ctx, const uint8_t *buf, int size, int
uint16_t frag_len; uint16_t frag_len;
char *info_hdr = &rtp_ctx->buf[4]; char *info_hdr = &rtp_ctx->buf[4];
if (size < DIRAC_PIC_NR_SIZE)
return AVERROR(EINVAL);
pic_nr = AV_RB32(&buf[0]); pic_nr = AV_RB32(&buf[0]);
buf += DIRAC_PIC_NR_SIZE; buf += DIRAC_PIC_NR_SIZE;
size -= DIRAC_PIC_NR_SIZE; size -= DIRAC_PIC_NR_SIZE;
@ -97,6 +100,7 @@ static void send_picture(AVFormatContext *ctx, const uint8_t *buf, int size, int
send_packet(ctx, DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT, 16, buf, frag_len, interlaced, second_field, size > 0 ? 0 : 1); send_packet(ctx, DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT, 16, buf, frag_len, interlaced, second_field, size > 0 ? 0 : 1);
buf += frag_len; buf += frag_len;
} }
return 0;
} }
void ff_rtp_send_vc2hq(AVFormatContext *ctx, const uint8_t *frame_buf, int frame_size, int interlaced) void ff_rtp_send_vc2hq(AVFormatContext *ctx, const uint8_t *frame_buf, int frame_size, int interlaced)
@ -110,16 +114,21 @@ void ff_rtp_send_vc2hq(AVFormatContext *ctx, const uint8_t *frame_buf, int frame
parse_code = unit[4]; parse_code = unit[4];
unit_size = AV_RB32(&unit[5]); unit_size = AV_RB32(&unit[5]);
if (unit_size > end - unit)
break;
switch (parse_code) { switch (parse_code) {
/* sequence header */ /* sequence header */
/* end of sequence */ /* end of sequence */
case DIRAC_PCODE_SEQ_HEADER: case DIRAC_PCODE_SEQ_HEADER:
case DIRAC_PCODE_END_SEQ: case DIRAC_PCODE_END_SEQ:
send_packet(ctx, parse_code, 0, unit + DIRAC_DATA_UNIT_HEADER_SIZE, unit_size - DIRAC_DATA_UNIT_HEADER_SIZE, 0, 0, 0); if (unit_size >= DIRAC_DATA_UNIT_HEADER_SIZE)
send_packet(ctx, parse_code, 0, unit + DIRAC_DATA_UNIT_HEADER_SIZE, unit_size - DIRAC_DATA_UNIT_HEADER_SIZE, 0, 0, 0);
break; break;
/* HQ picture */ /* HQ picture */
case DIRAC_PCODE_PICTURE_HQ: case DIRAC_PCODE_PICTURE_HQ:
send_picture(ctx, unit + DIRAC_DATA_UNIT_HEADER_SIZE, unit_size - DIRAC_DATA_UNIT_HEADER_SIZE, interlaced); if (unit_size >= DIRAC_DATA_UNIT_HEADER_SIZE)
send_picture(ctx, unit + DIRAC_DATA_UNIT_HEADER_SIZE, unit_size - DIRAC_DATA_UNIT_HEADER_SIZE, interlaced);
break; break;
/* parse codes without specification */ /* parse codes without specification */
case DIRAC_PCODE_AUX: case DIRAC_PCODE_AUX: