From ac3a618458823de6d626fe2ff4e86458643e359f Mon Sep 17 00:00:00 2001 From: Alfredo Cardigliano Date: Wed, 17 Jul 2019 22:06:00 +0200 Subject: Improved deserialization safety checks --- example/ndpiReader.c | 2 + src/lib/ndpi_utils.c | 118 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 74 insertions(+), 46 deletions(-) diff --git a/example/ndpiReader.c b/example/ndpiReader.c index e4dde12c6..237d80396 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -3163,6 +3163,8 @@ void serializerUnitTest() { break; default: + printf("serializerUnitTest: unsupported type %u detected!\n", et); + return; break; } } diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index 0f1b725ba..360b0d8b4 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -726,6 +726,12 @@ static u_int64_t ndpi_ntohll(u_int64_t v) { /* ********************************** */ +void ndpi_reset_serializer(ndpi_serializer *serializer) { + serializer->size_used = 2 * sizeof(u_int8_t); +} + +/* ********************************** */ + int ndpi_init_serializer(ndpi_serializer *serializer, ndpi_serialization_format fmt) { serializer->buffer_size = 8192; @@ -734,7 +740,7 @@ int ndpi_init_serializer(ndpi_serializer *serializer, serializer->buffer[0] = 1; /* version */ serializer->buffer[1] = (u_int8_t) fmt; - serializer->size_used = 2; + ndpi_reset_serializer(serializer); return(serializer->buffer ? 1 : -1); } @@ -750,12 +756,6 @@ void ndpi_term_serializer(ndpi_serializer *serializer) { /* ********************************** */ -void ndpi_reset_serializer(ndpi_serializer *serializer) { - serializer->size_used = 2; -} - -/* ********************************** */ - static int ndpi_extend_serializer_buffer(ndpi_serializer *serializer, u_int32_t min_len) { u_int32_t new_size; void *r; @@ -778,19 +778,6 @@ static int ndpi_extend_serializer_buffer(ndpi_serializer *serializer, u_int32_t /* ********************************** */ -static void ndpi_serialize_single_string(ndpi_serializer *serializer, - char *s, u_int32_t slen) { - u_int16_t l = htonl(slen); - - memcpy(&serializer->buffer[serializer->size_used], &l, sizeof(u_int16_t)); - serializer->size_used += 2; - - memcpy(&serializer->buffer[serializer->size_used], s, slen); - serializer->size_used += slen; -} - -/* ********************************** */ - static void ndpi_serialize_single_uint32(ndpi_serializer *serializer, u_int32_t s) { @@ -802,14 +789,6 @@ static void ndpi_serialize_single_uint32(ndpi_serializer *serializer, /* ********************************** */ -static void ndpi_deserialize_single_uint32(ndpi_serializer *serializer, - u_int32_t *s) { - *s = ntohl(*(u_int32_t*)&serializer->buffer[serializer->size_used]); - serializer->size_used += sizeof(u_int32_t); -} - -/* ********************************** */ - static void ndpi_serialize_single_uint64(ndpi_serializer *serializer, u_int64_t s) { @@ -821,21 +800,42 @@ static void ndpi_serialize_single_uint64(ndpi_serializer *serializer, /* ********************************** */ -static void ndpi_deserialize_single_uint64(ndpi_serializer *serializer, +static void ndpi_serialize_single_string(ndpi_serializer *serializer, + char *s, u_int32_t slen) { + u_int16_t l = htonl(slen); + + memcpy(&serializer->buffer[serializer->size_used], &l, sizeof(u_int16_t)); + serializer->size_used += sizeof(u_int16_t); + + memcpy(&serializer->buffer[serializer->size_used], s, slen); + serializer->size_used += slen; +} + +/* ********************************** */ + +static void ndpi_deserialize_single_uint32(ndpi_serializer *deserializer, + u_int32_t *s) { + *s = ntohl(*(u_int32_t*)&deserializer->buffer[deserializer->size_used]); + deserializer->size_used += sizeof(u_int32_t); +} + +/* ********************************** */ + +static void ndpi_deserialize_single_uint64(ndpi_serializer *deserializer, u_int64_t *s) { - *s = ndpi_ntohll(*(u_int64_t*)&serializer->buffer[serializer->size_used]); - serializer->size_used += sizeof(u_int64_t); + *s = ndpi_ntohll(*(u_int64_t*)&deserializer->buffer[deserializer->size_used]); + deserializer->size_used += sizeof(u_int64_t); } /* ********************************** */ -static void ndpi_deserialize_single_string(ndpi_serializer *serializer, +static void ndpi_deserialize_single_string(ndpi_serializer *deserializer, ndpi_string *v) { - v->str_len = ntohs(*((u_int16_t *) &serializer->buffer[serializer->size_used])); - serializer->size_used += 2; + v->str_len = ntohs(*((u_int16_t *) &deserializer->buffer[deserializer->size_used])); + deserializer->size_used += sizeof(u_int16_t); - v->str = (char*)&serializer->buffer[serializer->size_used]; - serializer->size_used += v->str_len; + v->str = (char*)&deserializer->buffer[deserializer->size_used]; + deserializer->size_used += v->str_len; } /* ********************************** */ @@ -1048,17 +1048,17 @@ int ndpi_serialize_string_string(ndpi_serializer *serializer, int ndpi_init_deserializer_buf(ndpi_deserializer *deserializer, u_int8_t *serialized_buffer, u_int32_t serialized_buffer_len) { - if(serialized_buffer_len < 3) + if(serialized_buffer_len < (2 * sizeof(u_int8_t))) return(-1); - deserializer->buffer_size = serialized_buffer_len; deserializer->buffer = serialized_buffer; if(deserializer->buffer[0] != 1) return(-2); /* Invalid version */ + deserializer->buffer_size = serialized_buffer_len; deserializer->fmt = deserializer->buffer[1]; - deserializer->size_used = 2; + ndpi_reset_serializer(deserializer); return(0); } @@ -1090,8 +1090,10 @@ ndpi_serialization_element_type ndpi_deserialize_get_nextitem_type(ndpi_deserial int ndpi_deserialize_end_of_record(ndpi_deserializer *deserializer) { if(ndpi_deserialize_get_nextitem_type(deserializer) == ndpi_serialization_end_of_record) { u_int32_t buff_diff = deserializer->buffer_size - deserializer->size_used; + u_int16_t expected = + sizeof(u_int8_t) /* type */; - if(buff_diff < 1) return(-2); + if(buff_diff < expected) return(-2); deserializer->size_used++; /* Skip element type */ @@ -1106,8 +1108,12 @@ int ndpi_deserialize_uint32_uint32(ndpi_deserializer *deserializer, u_int32_t *key, u_int32_t *value) { if(ndpi_deserialize_get_nextitem_type(deserializer) == ndpi_serialization_uint32_uint32) { u_int32_t buff_diff = deserializer->buffer_size - deserializer->size_used; + u_int16_t expected = + sizeof(u_int8_t) /* type */ + + sizeof(u_int32_t) /* key */ + + sizeof(u_int32_t); - if(buff_diff < 10) return(-2); + if(buff_diff < expected) return(-2); deserializer->size_used++; /* Skip element type */ ndpi_deserialize_single_uint32(deserializer, key); @@ -1124,8 +1130,12 @@ int ndpi_deserialize_uint32_uint64(ndpi_deserializer *deserializer, u_int32_t *key, u_int64_t *value) { if(ndpi_deserialize_get_nextitem_type(deserializer) == ndpi_serialization_uint32_uint64) { u_int32_t buff_diff = deserializer->buffer_size - deserializer->size_used; + u_int16_t expected = + sizeof(u_int8_t) /* type */ + + sizeof(u_int32_t) /* key */ + + sizeof(u_int64_t); - if(buff_diff < 10) return(-2); + if(buff_diff < expected) return(-2); deserializer->size_used++; /* Skip element type */ ndpi_deserialize_single_uint32(deserializer, key); @@ -1142,8 +1152,12 @@ int ndpi_deserialize_uint32_string(ndpi_deserializer *deserializer, u_int32_t *key, ndpi_string *value) { if(ndpi_deserialize_get_nextitem_type(deserializer) == ndpi_serialization_uint32_string) { u_int32_t buff_diff = deserializer->buffer_size - deserializer->size_used; + u_int32_t expected = + sizeof(u_int8_t) /* type */ + + sizeof(u_int32_t) /* key */ + + sizeof(u_int16_t) /* len */; - if(buff_diff < 7) return(-2); + if(buff_diff < expected) return(-2); deserializer->size_used++; /* Skip element type */ ndpi_deserialize_single_uint32(deserializer, key); @@ -1160,8 +1174,12 @@ int ndpi_deserialize_string_uint32(ndpi_deserializer *deserializer, ndpi_string *key, u_int32_t *value) { if(ndpi_deserialize_get_nextitem_type(deserializer) == ndpi_serialization_string_uint32) { u_int32_t buff_diff = deserializer->buffer_size - deserializer->size_used; + u_int32_t expected = + sizeof(u_int8_t) /* type */ + + sizeof(u_int16_t) /* key len */ + + sizeof(u_int32_t); - if(buff_diff < 7) return(-2); + if(buff_diff < expected) return(-2); deserializer->size_used++; /* Skip element type */ ndpi_deserialize_single_string(deserializer, key); @@ -1178,8 +1196,12 @@ int ndpi_deserialize_string_uint64(ndpi_deserializer *deserializer, ndpi_string *key, u_int64_t *value) { if(ndpi_deserialize_get_nextitem_type(deserializer) == ndpi_serialization_string_uint64) { u_int32_t buff_diff = deserializer->buffer_size - deserializer->size_used; + u_int32_t expected = + sizeof(u_int8_t) /* type */ + + sizeof(u_int16_t) /* key len */ + + sizeof(u_int64_t); - if(buff_diff < 11) return(-2); + if(buff_diff < expected) return(-2); deserializer->size_used++; /* Skip element type */ ndpi_deserialize_single_string(deserializer, key); @@ -1196,8 +1218,12 @@ int ndpi_deserialize_string_string(ndpi_deserializer *deserializer, ndpi_string *key, ndpi_string *value) { if(ndpi_deserialize_get_nextitem_type(deserializer) == ndpi_serialization_string_string) { u_int32_t buff_diff = deserializer->buffer_size - deserializer->size_used; + u_int32_t expected = + sizeof(u_int8_t) /* type */ + + sizeof(u_int16_t) /* key len */ + + sizeof(u_int16_t) /* len */; - if(buff_diff < 5) return(-2); + if(buff_diff < expected) return(-2); deserializer->size_used++; /* Skip element type */ ndpi_deserialize_single_string(deserializer, key); -- cgit v1.2.3