Skip to content

Commit 4974f04

Browse files
authored
Fuzz patch invalid tile size (#197)
* added protection code Signed-off-by: kp5.choi@samsung.com <kp5.choi@samsung.com> * bug fix in checking thread error Signed-off-by: kp5.choi@samsung.com <kp5.choi@samsung.com> --------- Signed-off-by: kp5.choi@samsung.com <kp5.choi@samsung.com>
1 parent cab6cea commit 4974f04

4 files changed

Lines changed: 57 additions & 44 deletions

File tree

src/oapv.c

Lines changed: 48 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,12 +1602,10 @@ static int dec_frm_prepare(oapvd_ctx_t *ctx, oapv_imgb_t *imgb)
16021602
return OAPV_OK;
16031603
}
16041604

1605-
static int dec_frm_finish(oapvd_ctx_t *ctx)
1605+
static void dec_frm_finish(oapvd_ctx_t *ctx)
16061606
{
1607-
oapv_mset(&ctx->bs, 0, sizeof(oapv_bs_t)); // clean data
16081607
imgb_release(ctx->imgb); // decrease reference cnout
16091608
ctx->imgb = NULL;
1610-
return OAPV_OK;
16111609
}
16121610

16131611
static int dec_tile_comp(oapvd_tile_t *tile, oapvd_ctx_t *ctx, oapvd_core_t *core, oapv_bs_t *bs, int c, int s_dst, void *dst)
@@ -1720,7 +1718,7 @@ static int dec_tile(oapvd_core_t *core, oapvd_tile_t *tile)
17201718
static int dec_thread_tile(void *arg)
17211719
{
17221720
oapv_bs_t bs;
1723-
int i, ret, run, tile_idx = 0, thread_ret = OAPV_OK;
1721+
int i, ret, run, tidx = 0, thread_ret = OAPV_OK;
17241722

17251723
oapvd_core_t *core = (oapvd_core_t *)arg;
17261724
oapvd_ctx_t *ctx = core->ctx;
@@ -1732,7 +1730,7 @@ static int dec_thread_tile(void *arg)
17321730
for(i = 0; i < ctx->num_tiles; i++) {
17331731
if(tile[i].stat == DEC_TILE_STAT_NOT_DECODED) {
17341732
tile[i].stat = DEC_TILE_STAT_ON_DECODING;
1735-
tile_idx = i;
1733+
tidx = i;
17361734
break;
17371735
}
17381736
}
@@ -1745,49 +1743,49 @@ static int dec_thread_tile(void *arg)
17451743
run = 1;
17461744
while(run) {
17471745
oapv_tpool_enter_cs(ctx->sync_obj);
1748-
if(tile[tile_idx].bs_beg != NULL) {
1746+
if(tile[tidx].bs_beg != NULL) {
17491747
run = 0;
17501748
}
17511749
oapv_tpool_leave_cs(ctx->sync_obj);
17521750
}
17531751
/* read tile size */
1754-
oapv_bsr_init(&bs, tile[tile_idx].bs_beg, OAPV_TILE_SIZE_LEN, NULL);
1755-
ret = oapvd_vlc_tile_size(&bs, &tile[tile_idx].tile_size);
1752+
oapv_bsr_init(&bs, tile[tidx].bs_beg, OAPV_TILE_SIZE_LEN, NULL);
1753+
ret = oapvd_vlc_tile_size(&bs, &tile[tidx].tile_size);
17561754
oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
17571755

1758-
/* check the tile data size */
1759-
oapv_assert_g((OAPV_TILE_SIZE_LEN + tile[tile_idx].tile_size) <= (ctx->bs.end - tile[tile_idx].bs_beg + 1), ERR);
1756+
/* check the tile size is smaller than input bitstream size */
1757+
oapv_assert_gv(tile[tidx].bs_beg + tile[tidx].tile_size + OAPV_TILE_SIZE_LEN <= ctx->bs.end, ret, OAPV_ERR_MALFORMED_BITSTREAM, ERR);
17601758

17611759
oapv_tpool_enter_cs(ctx->sync_obj);
1762-
if(tile_idx + 1 < ctx->num_tiles) {
1763-
tile[tile_idx + 1].bs_beg = tile[tile_idx].bs_beg + OAPV_TILE_SIZE_LEN + tile[tile_idx].tile_size;
1760+
if(tidx + 1 < ctx->num_tiles) {
1761+
tile[tidx + 1].bs_beg = tile[tidx].bs_beg + OAPV_TILE_SIZE_LEN + tile[tidx].tile_size;
17641762
}
17651763
else {
1766-
ctx->tile_end = tile[tile_idx].bs_beg + OAPV_TILE_SIZE_LEN + tile[tile_idx].tile_size;
1764+
ctx->tile_end = tile[tidx].bs_beg + OAPV_TILE_SIZE_LEN + tile[tidx].tile_size;
17671765
}
17681766
oapv_tpool_leave_cs(ctx->sync_obj);
17691767

1770-
ret = dec_tile(core, &tile[tile_idx]);
1768+
ret = dec_tile(core, &tile[tidx]);
17711769

17721770
oapv_tpool_enter_cs(ctx->sync_obj);
17731771
if (OAPV_SUCCEEDED(ret)) {
1774-
tile[tile_idx].stat = DEC_TILE_STAT_DECODED;
1772+
tile[tidx].stat = DEC_TILE_STAT_DECODED;
17751773
}
17761774
else {
1777-
tile[tile_idx].stat = ret;
1775+
tile[tidx].stat = ret;
17781776
thread_ret = ret;
17791777
}
1780-
tile[tile_idx].stat = OAPV_SUCCEEDED(ret) ? DEC_TILE_STAT_DECODED : ret;
1778+
tile[tidx].stat = OAPV_SUCCEEDED(ret) ? DEC_TILE_STAT_DECODED : ret;
17811779
oapv_tpool_leave_cs(ctx->sync_obj);
17821780
}
17831781
return thread_ret;
17841782

17851783
ERR:
17861784
oapv_tpool_enter_cs(ctx->sync_obj);
1787-
tile[tile_idx].stat = DEC_TILE_STAT_SIZE_ERROR;
1788-
if (tile_idx + 1 < ctx->num_tiles)
1785+
tile[tidx].stat = DEC_TILE_STAT_SIZE_ERROR;
1786+
if (tidx + 1 < ctx->num_tiles)
17891787
{
1790-
tile[tile_idx + 1].bs_beg = tile[tile_idx].bs_beg;
1788+
tile[tidx + 1].bs_beg = tile[tidx].bs_beg;
17911789
}
17921790
oapv_tpool_leave_cs(ctx->sync_obj);
17931791
return OAPV_ERR_MALFORMED_BITSTREAM;
@@ -1953,10 +1951,11 @@ int oapvd_decode(oapvd_t did, oapv_bitb_t *bitb, oapv_frms_t *ofrms, oapvm_t mid
19531951
int ret = OAPV_OK;
19541952
u32 pbu_size;
19551953
u32 cur_read_size = 0;
1956-
int frame_cnt = 0;
1954+
int nfrms = 0;
19571955

19581956
ctx = dec_id_to_ctx(did);
19591957
oapv_assert_rv(ctx, OAPV_ERR_INVALID_ARGUMENT);
1958+
oapv_mset(stat, 0, sizeof(oapvd_stat_t));
19601959

19611960
// read signature ('aPv1')
19621961
oapv_assert_rv(bitb->ssize > 4, OAPV_ERR_MALFORMED_BITSTREAM);
@@ -1987,15 +1986,15 @@ int oapvd_decode(oapvd_t did, oapv_bitb_t *bitb, oapv_frms_t *ofrms, oapvm_t mid
19871986
pbuh.pbu_type == OAPV_PBU_TYPE_DEPTH_FRAME ||
19881987
pbuh.pbu_type == OAPV_PBU_TYPE_ALPHA_FRAME) {
19891988

1990-
oapv_assert_gv(frame_cnt < OAPV_MAX_NUM_FRAMES, ret, OAPV_ERR_REACHED_MAX, ERR);
1989+
oapv_assert_gv(nfrms < OAPV_MAX_NUM_FRAMES, ret, OAPV_ERR_REACHED_MAX, ERR);
19911990

19921991
ret = oapvd_vlc_frame_header(bs, &ctx->fh);
19931992
oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
19941993

1995-
ret = dec_frm_prepare(ctx, ofrms->frm[frame_cnt].imgb);
1994+
ret = dec_frm_prepare(ctx, ofrms->frm[nfrms].imgb);
19961995
oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
19971996

1998-
int res, ret_thread;
1997+
int thread_ret;
19991998
oapv_tpool_t *tpool = ctx->tpool;
20001999
int parallel_task = 1;
20012000
int tidx = 0;
@@ -2007,49 +2006,54 @@ int oapvd_decode(oapvd_t did, oapv_bitb_t *bitb, oapv_frms_t *ofrms, oapvm_t mid
20072006
tpool->run(ctx->thread_id[tidx], dec_thread_tile,
20082007
(void *)ctx->core[tidx]);
20092008
}
2010-
ret_thread = dec_thread_tile((void *)ctx->core[tidx]);
2009+
ret = dec_thread_tile((void *)ctx->core[tidx]);
20112010
for(tidx = 0; tidx < parallel_task - 1; tidx++) {
2012-
tpool->join(ctx->thread_id[tidx], &res);
2013-
if(OAPV_FAILED(res)) {
2014-
ret_thread = res;
2011+
tpool->join(ctx->thread_id[tidx], &thread_ret);
2012+
if(OAPV_FAILED(thread_ret)) {
2013+
ret = thread_ret;
20152014
}
20162015
}
20172016
/****************************************************/
20182017

20192018
/* READ FILLER HERE !!! */
20202019

2021-
oapv_bsr_move(&ctx->bs, ctx->tile_end);
2022-
stat->read += BSR_GET_READ_BYTE(&ctx->bs);
2023-
2024-
fh_to_finfo(&ctx->fh, pbuh.pbu_type, pbuh.group_id, &stat->aui.frm_info[frame_cnt]);
2025-
if(ret == OAPV_OK && ctx->use_frm_hash) {
2020+
if(OAPV_SUCCEEDED(ret) && ctx->use_frm_hash) {
20262021
oapv_imgb_set_md5(ctx->imgb);
20272022
}
2028-
ret = dec_frm_finish(ctx);
2023+
else {
2024+
oapv_imgb_clr_md5(ctx->imgb);
2025+
}
2026+
// following function should be called even error cases,
2027+
// because input imgb's ref count needs to decreased.
2028+
// after this function, ctx->imgb cannot be accessed.
2029+
dec_frm_finish(ctx);
2030+
2031+
// check thread's return value
20292032
oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
20302033

2031-
ofrms->frm[frame_cnt].pbu_type = pbuh.pbu_type;
2032-
ofrms->frm[frame_cnt].group_id = pbuh.group_id;
2033-
stat->frm_size[frame_cnt] = pbu_size + 4 /* byte size of 'pbu_size' syntax */;
2034-
frame_cnt++;
2034+
fh_to_finfo(&ctx->fh, pbuh.pbu_type, pbuh.group_id, &stat->aui.frm_info[nfrms]);
2035+
2036+
ofrms->frm[nfrms].pbu_type = pbuh.pbu_type;
2037+
ofrms->frm[nfrms].group_id = pbuh.group_id;
2038+
stat->frm_size[nfrms] = pbu_size + 4 /* byte size of 'pbu_size' syntax */;
2039+
nfrms++;
20352040

2036-
/* here, check return values of each thread */
2037-
oapv_assert_gv(OAPV_SUCCEEDED(ret_thread), ret, ret_thread, ERR);
2041+
// go to the end of frame data for next PDU
2042+
oapv_bsr_move(bs, ctx->tile_end);
20382043
}
20392044
else if(pbuh.pbu_type == OAPV_PBU_TYPE_METADATA) {
20402045
ret = oapvd_vlc_metadata(bs, pbu_size, mid, pbuh.group_id);
20412046
oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
2042-
2043-
stat->read += BSR_GET_READ_BYTE(&ctx->bs);
20442047
}
20452048
else if(pbuh.pbu_type == OAPV_PBU_TYPE_FILLER) {
20462049
ret = oapvd_vlc_filler(bs, (pbu_size - 4));
20472050
oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
20482051
}
20492052
cur_read_size += pbu_size + 4 /* byte size of 'pbu_size' syntax */;
2053+
stat->read += BSR_GET_READ_BYTE(bs);
20502054
} while(cur_read_size < bitb->ssize);
2051-
stat->aui.num_frms = frame_cnt;
2052-
oapv_assert_gv(ofrms->num_frms == frame_cnt, ret, OAPV_ERR_MALFORMED_BITSTREAM, ERR);
2055+
stat->aui.num_frms = nfrms;
2056+
oapv_assert_gv(ofrms->num_frms == nfrms, ret, OAPV_ERR_MALFORMED_BITSTREAM, ERR);
20532057
return ret;
20542058

20552059
ERR:

src/oapv_bs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ static int bsr_flush(oapv_bs_t *bs, int byte)
190190

191191
void oapv_bsr_init(oapv_bs_t *bs, u8 *buf, u32 size, oapv_bs_fn_flush_t fn_flush)
192192
{
193+
oapv_mset(bs, 0, sizeof(oapv_bs_t));
194+
193195
bs->size = size;
194196
bs->cur = buf;
195197
bs->beg = buf;

src/oapv_util.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,11 @@ void oapv_imgb_set_md5(oapv_imgb_t *imgb)
277277
}
278278
}
279279

280+
void oapv_imgb_clr_md5(oapv_imgb_t *imgb)
281+
{
282+
oapv_mset(imgb->hash, 0, sizeof(imgb->hash));
283+
}
284+
280285
int oapv_set_md5_pld(oapvm_t mid, int group_id, oapv_imgb_t *rec)
281286
{
282287
oapv_imgb_set_md5(rec);

src/oapv_util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ typedef struct
143143

144144
/* MD5 Functions */
145145
void oapv_imgb_set_md5(oapv_imgb_t *imgb);
146+
void oapv_imgb_clr_md5(oapv_imgb_t *imgb);
147+
146148
void oapv_block_copy(s16 *src, int src_stride, s16 *dst, int dst_stride, int log2_copy_w, int log2_copy_h);
147149
int oapv_set_md5_pld(oapvm_t mid, int group_id, oapv_imgb_t *rec);
148150

0 commit comments

Comments
 (0)