Skip to content

Commit

Permalink
fixed mem leak in gsfdmx and be more strict on alloc sizes
Browse files Browse the repository at this point in the history
  • Loading branch information
jeanlf committed Jun 29, 2024
1 parent e325fdf commit e3fdb47
Showing 1 changed file with 61 additions and 9 deletions.
70 changes: 61 additions & 9 deletions src/filters/dmx_gsf.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ static GF_Err gsfdmx_read_prop(GF_BitStream *bs, GF_PropertyValue *p)
case GF_PROP_NAME:
p->type = GF_PROP_STRING_NO_COPY;
len = gsfdmx_read_vlen(bs);
if (len >= GF_UINT_MAX-1) {
if (len >= 0x1000000) {
p->value.string = NULL;
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[GSFDemux] invalid length in string property\n"));
return GF_NON_COMPLIANT_BITSTREAM;
Expand All @@ -344,17 +344,27 @@ static GF_Err gsfdmx_read_prop(GF_BitStream *bs, GF_PropertyValue *p)
p->type = GF_PROP_DATA_NO_COPY;
p->value.data.size = gsfdmx_read_vlen(bs);
if (!p->value.data.size) return GF_NON_COMPLIANT_BITSTREAM;
if (p->value.data.size >= 0x1000000) {
p->value.data.size = 0;
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[GSFDemux] invalid length in data property\n"));
return GF_NON_COMPLIANT_BITSTREAM;
}
p->value.data.ptr = gf_malloc(sizeof(char) * p->value.data.size);
gf_bs_read_data(bs, p->value.data.ptr, p->value.data.size);
break;

case GF_PROP_STRING_LIST:
len2 = gsfdmx_read_vlen(bs);
p->value.string_list.nb_items = len2;
if (p->value.string_list.nb_items >= 0x1000000) {
p->value.string_list.nb_items = 0;
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[GSFDemux] invalid length in string list property\n"));
return GF_NON_COMPLIANT_BITSTREAM;
}
p->value.string_list.vals = gf_malloc(sizeof(char*) * len2);
for (i=0; i<len2; i++) {
len = gsfdmx_read_vlen(bs);
if (len >= GF_UINT_MAX-1) {
if (len >= 0x1000000) {
for (u32 j=0; j<i; j++) {
gf_free(p->value.string_list.vals[j]);
p->value.string_list.vals[j] = NULL;
Expand All @@ -374,20 +384,35 @@ static GF_Err gsfdmx_read_prop(GF_BitStream *bs, GF_PropertyValue *p)
case GF_PROP_UINT_LIST:
case GF_PROP_SINT_LIST:
p->value.uint_list.nb_items = len = gsfdmx_read_vlen(bs);
if (p->value.uint_list.nb_items >= 0x1000000) {
p->value.uint_list.nb_items = 0;
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[GSFDemux] invalid length in list property\n"));
return GF_NON_COMPLIANT_BITSTREAM;
}
p->value.uint_list.vals = gf_malloc(sizeof(u32)*len);
for (i=0; i<len; i++) {
p->value.uint_list.vals[i] = gsfdmx_read_vlen(bs);
}
break;
case GF_PROP_4CC_LIST:
p->value.uint_list.nb_items = len = gsfdmx_read_vlen(bs);
if (p->value.uint_list.nb_items >= 0x1000000) {
p->value.uint_list.nb_items = 0;
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[GSFDemux] invalid length in 4CC list property\n"));
return GF_NON_COMPLIANT_BITSTREAM;
}
p->value.uint_list.vals = gf_malloc(sizeof(u32)*len);
for (i=0; i<len; i++) {
p->value.uint_list.vals[i] = gf_bs_read_u32(bs);
}
break;
case GF_PROP_VEC2I_LIST:
p->value.v2i_list.nb_items = len = gsfdmx_read_vlen(bs);
if (p->value.v2i_list.nb_items >= 0x1000000) {
p->value.v2i_list.nb_items = 0;
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[GSFDemux] invalid length in vec2i list property\n"));
return GF_NON_COMPLIANT_BITSTREAM;
}
p->value.v2i_list.vals = gf_malloc(sizeof(GF_PropVec2i)*len);
for (i=0; i<len; i++) {
p->value.v2i_list.vals[i].x = gsfdmx_read_vlen(bs);
Expand Down Expand Up @@ -513,7 +538,7 @@ static GF_Err gsfdmx_parse_pid_info(GF_Filter *filter, GSF_DemuxCtx *ctx, GSF_St
GF_PropertyValue p;

u32 len = gsfdmx_read_vlen(bs);
if (len >= GF_UINT_MAX-1)
if (len >=0x1000000)
return GF_BAD_PARAM;

char *pname = gf_malloc(sizeof(char)*(len+1));
Expand Down Expand Up @@ -591,6 +616,11 @@ static GF_Err gsfdmx_tune(GF_Filter *filter, GSF_DemuxCtx *ctx, char *pck_data,
len = gsfdmx_read_vlen(bs);
if (len) {
Bool wrongm=GF_FALSE;
if (len>0x100000) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[GSFDemux] wrong magic word size %u in stream config\n", len));
ctx->tune_error = GF_TRUE;
return GF_NOT_SUPPORTED;
}
char *magic = gf_malloc(sizeof(char)*len);
gf_bs_read_data(bs, magic, len);

Expand Down Expand Up @@ -629,9 +659,17 @@ static GFINLINE GSF_Packet *gsfdmx_get_packet(GSF_DemuxCtx *ctx, GSF_Stream *gst
if ((frame_sn>=0) || pck_frag) {
while (( gpck = gf_list_enum(gst->packets, &i))) {
if (gpck->frame_sn == frame_sn) {
gf_assert(gpck->pck_type == pkt_type);
gf_assert(gpck->full_block_size == frame_size);

if ((gpck->pck_type == pkt_type) && (gpck->full_block_size == frame_size))
break;
if (gpck->pck) {
gf_filter_pck_discard(gpck->pck);
gpck->pck=NULL;
}
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[GSFDemux] Corrupted packet SN %u - discarding\n", frame_sn));
gf_list_rem(gst->packets, i-1);
gsfdmx_pck_reset(gpck);
gf_list_add(ctx->pck_res, gpck);
gpck = NULL;
break;
}
gpck = NULL;
Expand Down Expand Up @@ -863,11 +901,20 @@ GF_Err gsfdmx_read_data_pck(GSF_DemuxCtx *ctx, GSF_Stream *gst, GSF_Packet *gpck
while (nb_props) {
GF_Err e;
GF_PropertyValue p;
char *pname;
char *pname=NULL;
memset(&p, 0, sizeof(GF_PropertyValue));
u32 len = gsfdmx_read_vlen(bs);
pname = gf_malloc(sizeof(char)*(len+1) );
gf_bs_read_data(bs, pname, len);
if (len<=0x1000000) {
pname = gf_malloc(sizeof(char)*(len+1) );
if (pname)
gf_bs_read_data(bs, pname, len);
}
if (!pname) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[GSFDemux] Invalid property size %d\n", len ));
gf_filter_pck_discard(gpck->pck);
gpck->pck = NULL;
return GF_NON_COMPLIANT_BITSTREAM;
}
pname[len] = 0;
p.type = gf_bs_read_u8(bs);
if (p.type==GF_PROP_FORBIDDEN) {
Expand Down Expand Up @@ -1043,6 +1090,11 @@ static GF_Err gsfdmx_process_packets(GF_Filter *filter, GSF_DemuxCtx *ctx, GSF_S
gpck->pck = NULL;
break;
default:
if (gpck->pck) {
gf_filter_pck_discard(gpck->pck);
gpck->pck=NULL;
}
GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[GSFDemux] unknown packet type %d ignoring\n", gpck->pck_type));
e = GF_OK;
break;
}
Expand Down

0 comments on commit e3fdb47

Please sign in to comment.