@@ -245,13 +245,22 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h)
245245 _len -= _off; \
246246 } while (0);
247247
248+ #define CHECK_CHUNK_SIZE (_len , _type ) \
249+ do { \
250+ if ((_len) != sizeof(_type)) { \
251+ LM_ERR("invalid HEPv3 chunk %u length %u, expected %zu\n", \
252+ chunk_id, (unsigned int)(_len), sizeof(_type)); \
253+ goto error; \
254+ } \
255+ } while (0);
256+
248257 int rc ;
249258
250259 unsigned char * compressed_payload ;
251260 unsigned long compress_len ;
252261
253262 struct hepv3 h3 ;
254- unsigned short tlen ;
263+ unsigned short tlen , chunk_len ;
255264 unsigned long decompress_len ;
256265
257266 generic_chunk_t * gen_chunk , * it ;
@@ -263,19 +272,44 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h)
263272
264273 h -> version = 3 ;
265274
275+ if (len < sizeof (hep_ctrl_t )) {
276+ LM_ERR ("invalid HEPv3 packet length %d\n" , len );
277+ return -1 ;
278+ }
279+
266280 tlen = ntohs (((hep_ctrl_t * )buf )-> length );
281+ if (tlen < sizeof (hep_ctrl_t ) || tlen > len ) {
282+ LM_ERR ("invalid HEPv3 advertised length %u for packet length %d\n" ,
283+ (unsigned int )tlen , len );
284+ return -1 ;
285+ }
267286
268287 buf += sizeof (hep_ctrl_t );
269288 tlen -= sizeof (hep_ctrl_t );
270289
271290 memset ( & h3 , 0 , sizeof (struct hepv3 ));
272291
273292 while (tlen > 0 ) {
293+ if (tlen < sizeof (hep_chunk_t )) {
294+ LM_ERR ("truncated HEPv3 chunk header, remaining length %u\n" ,
295+ (unsigned int )tlen );
296+ goto error ;
297+ }
298+
274299 /* we don't look at vendor id; we only need to parse the buffer */
275- chunk_id = ((hep_chunk_t * )buf )-> type_id ;
300+ chunk_id = ntohs (((hep_chunk_t * )buf )-> type_id );
301+ chunk_len = ntohs (((hep_chunk_t * )buf )-> length );
302+
303+ if (chunk_len < sizeof (hep_chunk_t ) || chunk_len > tlen ) {
304+ LM_ERR ("invalid HEPv3 chunk %u length %u, remaining length %u\n" ,
305+ chunk_id , (unsigned int )chunk_len , (unsigned int )tlen );
306+ goto error ;
307+ }
276308
277- switch (ntohs ( chunk_id ) ) {
309+ switch (chunk_id ) {
278310 case HEP_PROTO_FAMILY :
311+ CHECK_CHUNK_SIZE (chunk_len , hep_chunk_uint8_t );
312+
279313 /* ip family*/
280314 h3 .hg .ip_family = * ((hep_chunk_uint8_t * )buf );
281315
@@ -284,6 +318,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h)
284318
285319 break ;
286320 case HEP_PROTO_ID :
321+ CHECK_CHUNK_SIZE (chunk_len , hep_chunk_uint8_t );
322+
287323 /* ip protocol ID*/
288324 h3 .hg .ip_proto = * ((hep_chunk_uint8_t * )buf );
289325
@@ -292,6 +328,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h)
292328
293329 break ;
294330 case HEP_IPV4_SRC :
331+ CHECK_CHUNK_SIZE (chunk_len , hep_chunk_ip4_t );
332+
295333 /* ipv4 source */
296334 h3 .addr .ip4_addr .src_ip4 = * ((hep_chunk_ip4_t * )buf );
297335
@@ -300,6 +338,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h)
300338
301339 break ;
302340 case HEP_IPV4_DST :
341+ CHECK_CHUNK_SIZE (chunk_len , hep_chunk_ip4_t );
342+
303343 /* ipv4 dest */
304344 h3 .addr .ip4_addr .dst_ip4 = * ((hep_chunk_ip4_t * )buf );
305345
@@ -308,6 +348,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h)
308348
309349 break ;
310350 case HEP_IPV6_SRC :
351+ CHECK_CHUNK_SIZE (chunk_len , hep_chunk_ip6_t );
352+
311353 /* ipv6 source */
312354 h3 .addr .ip6_addr .src_ip6 = * ((hep_chunk_ip6_t * )buf );
313355
@@ -316,6 +358,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h)
316358
317359 break ;
318360 case HEP_IPV6_DST :
361+ CHECK_CHUNK_SIZE (chunk_len , hep_chunk_ip6_t );
362+
319363 /* ipv6 dest */
320364 h3 .addr .ip6_addr .dst_ip6 = * ((hep_chunk_ip6_t * )buf );
321365
@@ -324,6 +368,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h)
324368
325369 break ;
326370 case HEP_SRC_PORT :
371+ CHECK_CHUNK_SIZE (chunk_len , hep_chunk_uint16_t );
372+
327373 /* source port */
328374 h3 .hg .src_port = * ((hep_chunk_uint16_t * )buf );
329375
@@ -334,6 +380,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h)
334380
335381 break ;
336382 case HEP_DST_PORT :
383+ CHECK_CHUNK_SIZE (chunk_len , hep_chunk_uint16_t );
384+
337385 /* dest port */
338386 h3 .hg .dst_port = * ((hep_chunk_uint16_t * )buf );
339387
@@ -344,6 +392,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h)
344392
345393 break ;
346394 case HEP_TIMESTAMP :
395+ CHECK_CHUNK_SIZE (chunk_len , hep_chunk_uint32_t );
396+
347397 /* timestamp */
348398 h3 .hg .time_sec = * ((hep_chunk_uint32_t * )buf );
349399
@@ -354,6 +404,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h)
354404
355405 break ;
356406 case HEP_TIMESTAMP_US :
407+ CHECK_CHUNK_SIZE (chunk_len , hep_chunk_uint32_t );
408+
357409 /* timestamp microsecs offset */
358410 h3 .hg .time_usec = * ((hep_chunk_uint32_t * )buf );
359411
@@ -364,6 +416,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h)
364416
365417 break ;
366418 case HEP_PROTO_TYPE :
419+ CHECK_CHUNK_SIZE (chunk_len , hep_chunk_uint8_t );
420+
367421 /* proto type */
368422 h3 .hg .proto_t = * ((hep_chunk_uint8_t * )buf );
369423
@@ -372,6 +426,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h)
372426
373427 break ;
374428 case HEP_AGENT_ID :
429+ CHECK_CHUNK_SIZE (chunk_len , hep_chunk_uint32_t );
430+
375431 /* capture agent id */
376432 h3 .hg .capt_id = * ((hep_chunk_uint32_t * )buf );
377433
@@ -426,7 +482,7 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h)
426482 * locking will be required */
427483 if ((gen_chunk = shm_malloc (sizeof (generic_chunk_t )))== NULL ) {
428484 LM_ERR ("no more pkg mem!\n" );
429- return -1 ;
485+ goto error ;
430486 }
431487
432488 memset (gen_chunk , 0 , sizeof (generic_chunk_t ));
@@ -439,7 +495,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h)
439495
440496 if (gen_chunk -> data == NULL ) {
441497 LM_ERR ("no more shared memory!\n" );
442- return -1 ;
498+ shm_free (gen_chunk );
499+ goto error ;
443500 }
444501
445502 memcpy (gen_chunk -> data , (char * )buf + sizeof (hep_chunk_t ),
@@ -463,6 +520,18 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h)
463520 h -> u .hepv3 = h3 ;
464521
465522 return 0 ;
523+
524+ error :
525+ while (h3 .chunk_list ) {
526+ it = h3 .chunk_list ;
527+ h3 .chunk_list = it -> next ;
528+ shm_free (it -> data );
529+ shm_free (it );
530+ }
531+ if (decompressed_payload .s )
532+ pkg_free (decompressed_payload .s );
533+ #undef CHECK_CHUNK_SIZE
534+ return -1 ;
466535}
467536
468537static int
0 commit comments