diff options
author | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2022-12-06 17:41:58 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-06 17:41:58 +0100 |
commit | ada4fe4aa8f88300cfc0dbe6ee965975274b1c40 (patch) | |
tree | 08010d2055d0159330ded8e5c15113deb0c41c3b | |
parent | 946c3dba0f6c393c2e41b98103cec3e7308fbf2c (diff) |
fuzz: add a new fuzzer testing memory allocation failures (#1818)
Try to fuzz error paths triggered by allocation errors.
Fix some errors already found by this new fuzzer.
Basic idea taken from: https://github.com/harfbuzz/harfbuzz/pull/2566/files
`FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION` is a standard define used to
(not)compile specific code in fuzzing builds.
See: https://llvm.org/docs/LibFuzzer.html
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | example/reader_util.c | 32 | ||||
-rw-r--r-- | fuzz/Makefile.am | 22 | ||||
-rw-r--r-- | fuzz/fuzz_ndpi_reader.c | 33 | ||||
-rw-r--r-- | src/lib/ndpi_analyze.c | 37 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 7 | ||||
-rw-r--r-- | src/lib/ndpi_serializer.c | 4 | ||||
-rw-r--r-- | src/lib/ndpi_utils.c | 3 | ||||
-rw-r--r-- | src/lib/protocols/quic.c | 23 | ||||
-rw-r--r-- | src/lib/protocols/tls.c | 27 | ||||
-rw-r--r-- | src/lib/third_party/src/libcache.c | 5 |
11 files changed, 156 insertions, 41 deletions
diff --git a/.gitignore b/.gitignore index d58335884..217610788 100644 --- a/.gitignore +++ b/.gitignore @@ -52,7 +52,11 @@ /fuzz/Makefile /fuzz/fuzz_ndpi_reader /fuzz/fuzz_process_packet +/fuzz/fuzz_ndpi_reader_alloc_fail /fuzz/fuzz_quic_get_crypto_data +/fuzz/fuzz_ndpi_reader_alloc_fail_seed_corpus.zip +/fuzz/fuzz_ndpi_reader_seed_corpus.zip +/fuzz/fuzz_quic_get_crypto_data_seed_corpus.zip /influxdb/Makefile /install-sh /libndpi.pc diff --git a/example/reader_util.c b/example/reader_util.c index f3d7f73ff..276215eff 100644 --- a/example/reader_util.c +++ b/example/reader_util.c @@ -858,7 +858,10 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow struct ndpi_flow_info *newflow = (struct ndpi_flow_info*)ndpi_malloc(sizeof(struct ndpi_flow_info)); if(newflow == NULL) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* Avoid too much logging while fuzzing */ LOG(NDPI_LOG_ERROR, "[NDPI] %s(1): not enough memory\n", __FUNCTION__); +#endif return(NULL); } else workflow->num_allocated_flows++; @@ -899,12 +902,11 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow } if((newflow->ndpi_flow = ndpi_flow_malloc(SIZEOF_FLOW_STRUCT)) == NULL) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* Avoid too much logging while fuzzing */ LOG(NDPI_LOG_ERROR, "[NDPI] %s(2): not enough memory\n", __FUNCTION__); -#ifdef DIRECTION_BINS - ndpi_free_bin(&newflow->payload_len_bin_src2dst), ndpi_free_bin(&newflow->payload_len_bin_dst2src); -#else - ndpi_free_bin(&newflow->payload_len_bin); #endif + ndpi_flow_info_free_data(newflow); ndpi_free(newflow); return(NULL); } else @@ -916,11 +918,17 @@ static struct ndpi_flow_info *get_ndpi_flow_info(struct ndpi_workflow * workflow workflow->ndpi_serialization_format) != 0) { LOG(NDPI_LOG_ERROR, "ndpi serializer init failed\n"); - exit(-1); + ndpi_flow_info_free_data(newflow); + ndpi_free(newflow); + return(NULL); } } - ndpi_tsearch(newflow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp); /* Add */ + if(ndpi_tsearch(newflow, &workflow->ndpi_flows_root[idx], ndpi_workflow_node_cmp) == NULL) { /* Add */ + ndpi_flow_info_free_data(newflow); + ndpi_free(newflow); + return(NULL); + } workflow->stats.ndpi_flow_count++; if(*proto == IPPROTO_TCP) workflow->stats.flow_count[0]++; @@ -1099,13 +1107,15 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl if(flow->ndpi_flow->protos.bittorrent.hash[0] != '\0') { flow->bittorent_hash = ndpi_malloc(sizeof(flow->ndpi_flow->protos.bittorrent.hash) * 2 + 1); - for(i=0, j = 0; i < sizeof(flow->ndpi_flow->protos.bittorrent.hash); i++) { - sprintf(&flow->bittorent_hash[j], "%02x", - flow->ndpi_flow->protos.bittorrent.hash[i]); + if(flow->bittorent_hash) { + for(i=0, j = 0; i < sizeof(flow->ndpi_flow->protos.bittorrent.hash); i++) { + sprintf(&flow->bittorent_hash[j], "%02x", + flow->ndpi_flow->protos.bittorrent.hash[i]); - j += 2; + j += 2; + } + flow->bittorent_hash[j] = '\0'; } - flow->bittorent_hash[j] = '\0'; } } /* TIVOCONNECT */ diff --git a/fuzz/Makefile.am b/fuzz/Makefile.am index d739fb00a..7f4f2de99 100644 --- a/fuzz/Makefile.am +++ b/fuzz/Makefile.am @@ -1,4 +1,4 @@ -bin_PROGRAMS = fuzz_process_packet fuzz_ndpi_reader fuzz_quic_get_crypto_data +bin_PROGRAMS = fuzz_process_packet fuzz_ndpi_reader fuzz_ndpi_reader_alloc_fail fuzz_quic_get_crypto_data fuzz_process_packet_SOURCES = fuzz_process_packet.c fuzz_process_packet_CFLAGS = @NDPI_CFLAGS@ $(CXXFLAGS) @@ -26,6 +26,19 @@ fuzz_ndpi_reader_LINK=$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXX) @NDPI_CFLAGS@ $(AM_CXXFLAGS) $(CXXFLAGS) \ $(fuzz_ndpi_reader_LDFLAGS) @NDPI_LDFLAGS@ $(LDFLAGS) -o $@ +fuzz_ndpi_reader_alloc_fail_SOURCES = fuzz_ndpi_reader.c ../example/reader_util.c +fuzz_ndpi_reader_alloc_fail_CFLAGS = -I../example/ @NDPI_CFLAGS@ $(CXXFLAGS) -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -DENABLE_MEM_ALLOC_FAILURES +fuzz_ndpi_reader_alloc_fail_LDADD = ../src/lib/libndpi.a +fuzz_ndpi_reader_alloc_fail_LDFLAGS = $(PCAP_LIB) $(ADDITIONAL_LIBS) $(LIBS) +if HAS_FUZZLDFLAGS +fuzz_ndpi_reader_alloc_fail_CFLAGS += $(LIB_FUZZING_ENGINE) +fuzz_ndpi_reader_alloc_fail_LDFLAGS += $(LIB_FUZZING_ENGINE) +endif +# force usage of CXX for linker +fuzz_ndpi_reader_alloc_fail_LINK=$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXX) @NDPI_CFLAGS@ $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(fuzz_ndpi_reader_alloc_fail_LDFLAGS) @NDPI_LDFLAGS@ $(LDFLAGS) -o $@ + fuzz_quic_get_crypto_data_SOURCES = fuzz_quic_get_crypto_data.c fuzz_quic_get_crypto_data_CFLAGS = @NDPI_CFLAGS@ $(CXXFLAGS) fuzz_quic_get_crypto_data_LDADD = ../src/lib/libndpi.a @@ -46,15 +59,20 @@ testpcaps := $(wildcard ../tests/pcap/*.pcap*) fuzz_ndpi_reader_seed_corpus.zip: $(testpcaps) zip -r fuzz_ndpi_reader_seed_corpus.zip $(testpcaps) +fuzz_ndpi_reader_alloc_fail_seed_corpus.zip: $(testpcaps) + zip -r fuzz_ndpi_reader_alloc_fail_seed_corpus.zip $(testpcaps) + files_corpus_fuzz_quic_get_crypto_data := $(wildcard corpus/fuzz_quic_get_crypto_data/*) fuzz_quic_get_crypto_data_seed_corpus.zip: $(files_corpus_fuzz_quic_get_crypto_data) zip -r fuzz_quic_get_crypto_data_seed_corpus.zip $(files_corpus_fuzz_quic_get_crypto_data) -corpus: fuzz_quic_get_crypto_data_seed_corpus.zip +corpus: fuzz_ndpi_reader_seed_corpus.zip fuzz_ndpi_reader_alloc_fail_seed_corpus.zip fuzz_quic_get_crypto_data_seed_corpus.zip distdir: find . -type d | xargs -I'{}' mkdir -p '$(distdir)/{}' find . -type f -name '*.c' \ -o -name '*.am' \ -o -name '*.bin' | xargs -I'{}' cp '{}' '$(distdir)/{}' + +all: corpus diff --git a/fuzz/fuzz_ndpi_reader.c b/fuzz/fuzz_ndpi_reader.c index 1adba5939..76f2d7263 100644 --- a/fuzz/fuzz_ndpi_reader.c +++ b/fuzz/fuzz_ndpi_reader.c @@ -23,6 +23,26 @@ int malloc_size_stats = 0; int max_malloc_bins = 0; struct ndpi_bin malloc_bins; /* unused */ +#ifdef ENABLE_MEM_ALLOC_FAILURES + +static int mem_alloc_state = 0; + +static int fastrand () +{ + if(!mem_alloc_state) return 1; /* No failures */ + mem_alloc_state = (214013 * mem_alloc_state + 2531011); + return (mem_alloc_state >> 16) & 0x7FFF; +} + +static void *malloc_wrapper(size_t size) { + return (fastrand () % 16) ? malloc (size) : NULL; +} +static void free_wrapper(void *freeable) { + free(freeable); +} + +#endif + FILE *bufferToFile(const uint8_t *Data, size_t Size) { FILE *fd; fd = tmpfile(); @@ -71,8 +91,17 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { memset(workflow->stats.protocol_flows, 0, sizeof(workflow->stats.protocol_flows)); ndpi_finalize_initialization(workflow->ndpi_struct); +#ifdef ENABLE_MEM_ALLOC_FAILURES + set_ndpi_malloc(malloc_wrapper); + set_ndpi_free(free_wrapper); + /* Don't fail memory allocations until init phase is done */ +#endif } +#ifdef ENABLE_MEM_ALLOC_FAILURES + mem_alloc_state = Size; +#endif + fd = bufferToFile(Data, Size); if (fd == NULL) return 0; @@ -92,6 +121,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { workflow->pcap_handle = pkts; /* Init flow tree */ workflow->ndpi_flows_root = ndpi_calloc(workflow->prefs.num_roots, sizeof(void *)); + if(!workflow->ndpi_flows_root) { + pcap_close(pkts); + return 0; + } header = NULL; r = pcap_next_ex(pkts, &header, &pkt); diff --git a/src/lib/ndpi_analyze.c b/src/lib/ndpi_analyze.c index e3418afb4..66b68e0b2 100644 --- a/src/lib/ndpi_analyze.c +++ b/src/lib/ndpi_analyze.c @@ -44,6 +44,8 @@ void ndpi_init_data_analysis(struct ndpi_analyze_struct *ret, u_int16_t _max_ser len = sizeof(u_int32_t) * ret->num_values_array_len; if((ret->values = ndpi_malloc(len)) != NULL) memset(ret->values, 0, len); + else + ret->num_values_array_len = 0; } } @@ -61,7 +63,7 @@ struct ndpi_analyze_struct* ndpi_alloc_data_analysis(u_int16_t _max_series_len) /* ********************************************************************************* */ void ndpi_free_data_analysis(struct ndpi_analyze_struct *d, u_int8_t free_pointer) { - if(d->values) ndpi_free(d->values); + if(d && d->values) ndpi_free(d->values); if(free_pointer) ndpi_free(d); } @@ -85,6 +87,9 @@ void ndpi_reset_data_analysis(struct ndpi_analyze_struct *d) { Add a new point to analyze */ void ndpi_data_add_value(struct ndpi_analyze_struct *s, const u_int32_t value) { + if(!s) + return; + if(s->sum_total == 0) s->min_val = s->max_val = value; else { @@ -115,13 +120,15 @@ void ndpi_data_add_value(struct ndpi_analyze_struct *s, const u_int32_t value) { /* Compute the average on all values */ float ndpi_data_average(struct ndpi_analyze_struct *s) { + if(!s) + return(0); return((s->num_data_entries == 0) ? 0 : ((float)s->sum_total / (float)s->num_data_entries)); } /* ********************************************************************************* */ u_int32_t ndpi_data_last(struct ndpi_analyze_struct *s) { - if((s->num_data_entries == 0) || (s->sum_total == 0)) + if((!s) || (s->num_data_entries == 0) || (s->sum_total == 0)) return(0); if(s->next_value_insert_index == 0) @@ -138,6 +145,8 @@ u_int32_t ndpi_data_max(struct ndpi_analyze_struct *s) { return(s->max_val); } /* Compute the variance on all values */ float ndpi_data_variance(struct ndpi_analyze_struct *s) { + if(!s) + return(0); float v = s->num_data_entries ? ((float)s->stddev.sum_square_total - ((float)s->sum_total * (float)s->sum_total / (float)s->num_data_entries)) / (float)s->num_data_entries : 0.0; return((v < 0 /* rounding problem */) ? 0 : v); } @@ -307,6 +316,9 @@ double ndpi_hll_count(struct ndpi_hll *hll) { /* ********************************************************************************* */ int ndpi_init_bin(struct ndpi_bin *b, enum ndpi_bin_family f, u_int16_t num_bins) { + if(!b) + return(-1); + b->num_bins = num_bins, b->family = f, b->is_empty = 1; switch(f) { @@ -337,6 +349,9 @@ int ndpi_init_bin(struct ndpi_bin *b, enum ndpi_bin_family f, u_int16_t num_bins /* ********************************************************************************* */ void ndpi_free_bin(struct ndpi_bin *b) { + if(!b || !b->u.bins8) + return; + switch(b->family) { case ndpi_bin_family8: ndpi_free(b->u.bins8); @@ -358,7 +373,7 @@ void ndpi_free_bin(struct ndpi_bin *b) { struct ndpi_bin* ndpi_clone_bin(struct ndpi_bin *b) { struct ndpi_bin *out = (struct ndpi_bin*)ndpi_malloc(sizeof(struct ndpi_bin)); - if(!out) return(NULL); + if(!b || !b->u.bins8 || !out) return(NULL); out->num_bins = b->num_bins, out->family = b->family, out->is_empty = b->is_empty; @@ -402,6 +417,9 @@ struct ndpi_bin* ndpi_clone_bin(struct ndpi_bin *b) { /* ********************************************************************************* */ void ndpi_set_bin(struct ndpi_bin *b, u_int16_t slot_id, u_int64_t val) { + if(!b || !b->u.bins8) + return; + if(slot_id >= b->num_bins) slot_id = 0; switch(b->family) { @@ -423,6 +441,9 @@ void ndpi_set_bin(struct ndpi_bin *b, u_int16_t slot_id, u_int64_t val) { /* ********************************************************************************* */ void ndpi_inc_bin(struct ndpi_bin *b, u_int16_t slot_id, u_int64_t val) { + if(!b || !b->u.bins8) + return; + b->is_empty = 0; if(slot_id >= b->num_bins) slot_id = 0; @@ -446,6 +467,9 @@ void ndpi_inc_bin(struct ndpi_bin *b, u_int16_t slot_id, u_int64_t val) { /* ********************************************************************************* */ u_int64_t ndpi_get_bin_value(struct ndpi_bin *b, u_int16_t slot_id) { + if(!b || !b->u.bins8) + return(0); + if(slot_id >= b->num_bins) slot_id = 0; switch(b->family) { @@ -469,6 +493,9 @@ u_int64_t ndpi_get_bin_value(struct ndpi_bin *b, u_int16_t slot_id) { /* ********************************************************************************* */ void ndpi_reset_bin(struct ndpi_bin *b) { + if(!b || !b->u.bins8) + return; + b->is_empty = 1; switch(b->family) { @@ -495,7 +522,7 @@ void ndpi_normalize_bin(struct ndpi_bin *b) { u_int16_t i; u_int32_t tot = 0; - if(b->is_empty) return; + if(!b || b->is_empty) return; switch(b->family) { case ndpi_bin_family8: @@ -542,7 +569,7 @@ char* ndpi_print_bin(struct ndpi_bin *b, u_int8_t normalize_first, char *out_buf u_int16_t i; u_int len = 0; - if(!out_buf) return(out_buf); else out_buf[0] = '\0'; + if(!b || !out_buf) return(out_buf); else out_buf[0] = '\0'; if(normalize_first) ndpi_normalize_bin(b); diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 1bc286f4d..38820dc0a 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -5100,11 +5100,10 @@ void ndpi_free_flow_data(struct ndpi_flow_struct* flow) { } if(flow->l4_proto == IPPROTO_UDP) { - if(flow->l4.udp.quic_reasm_buf){ + if(flow->l4.udp.quic_reasm_buf) ndpi_free(flow->l4.udp.quic_reasm_buf); - if(flow->l4.udp.quic_reasm_buf_bitmap) - ndpi_free(flow->l4.udp.quic_reasm_buf_bitmap); - } + if(flow->l4.udp.quic_reasm_buf_bitmap) + ndpi_free(flow->l4.udp.quic_reasm_buf_bitmap); } } diff --git a/src/lib/ndpi_serializer.c b/src/lib/ndpi_serializer.c index f383d471c..f8652dbc3 100644 --- a/src/lib/ndpi_serializer.c +++ b/src/lib/ndpi_serializer.c @@ -224,8 +224,10 @@ int ndpi_init_serializer_ll(ndpi_serializer *_serializer, /* nothing to do */ } else if (fmt == ndpi_serialization_format_csv) { - if (ndpi_init_serializer_buffer(&serializer->header, NDPI_SERIALIZER_DEFAULT_HEADER_SIZE) != 0) + if (ndpi_init_serializer_buffer(&serializer->header, NDPI_SERIALIZER_DEFAULT_HEADER_SIZE) != 0) { + ndpi_term_serializer(_serializer); return(-1); + } } else /* ndpi_serialization_format_tlv */ { serializer->buffer.data[0] = 1; /* version */ diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index ee6f076ab..b0922acd7 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -131,8 +131,9 @@ void * ndpi_tsearch(const void *vkey, void **vrootp, *rootp = q; /* link new node to old */ q->key = key; /* initialize new node */ q->left = q->right = (ndpi_node *)0; + return ((void *)q->key); } - return ((void *)q->key); + return ((void *)0); } /* ****************************************** */ diff --git a/src/lib/protocols/quic.c b/src/lib/protocols/quic.c index 7f405b433..2f9a0927c 100644 --- a/src/lib/protocols/quic.c +++ b/src/lib/protocols/quic.c @@ -477,8 +477,10 @@ static int tls13_hkdf_expand_label_context(struct ndpi_detection_module_struct * #endif *out = (uint8_t *)ndpi_malloc(out_len); - if(!*out) + if(!*out) { + ndpi_free(info_data); return 0; + } err = hkdf_expand(md, secret->data, secret->data_len, info_data, info_len, *out, out_len); ndpi_free(info_data); @@ -655,8 +657,15 @@ static int quic_pp_cipher_prepare(struct ndpi_detection_module_struct *ndpi_stru static int quic_ciphers_prepare(struct ndpi_detection_module_struct *ndpi_struct, quic_ciphers *ciphers, int hash_algo, int cipher_algo, int cipher_mode, uint8_t *secret, u_int32_t version) { - return quic_hp_cipher_prepare(ndpi_struct, &ciphers->hp_cipher, hash_algo, cipher_algo, secret, version) && - quic_pp_cipher_prepare(ndpi_struct, &ciphers->pp_cipher, hash_algo, cipher_algo, cipher_mode, secret, version); + int ret; + + ret = quic_hp_cipher_prepare(ndpi_struct, &ciphers->hp_cipher, hash_algo, cipher_algo, secret, version); + if(ret != 1) + return ret; + ret = quic_pp_cipher_prepare(ndpi_struct, &ciphers->pp_cipher, hash_algo, cipher_algo, cipher_mode, secret, version); + if(ret != 1) + quic_hp_cipher_reset(&ciphers->hp_cipher); + return ret; } /** * Given a header protection cipher, a buffer and the packet number offset, @@ -1013,7 +1022,7 @@ static void update_reasm_buf_bitmap(u_int8_t *buffer_bitmap, const u_int32_t recv_pos, const u_int32_t recv_len) { - if (!recv_len || !buffer_bitmap_size || recv_pos + recv_len > buffer_bitmap_size * 8) + if (!recv_len || !buffer_bitmap_size || !buffer_bitmap || recv_pos + recv_len > buffer_bitmap_size * 8) return; const u_int32_t start_byte = recv_pos / 8; const u_int32_t end_byte = (recv_pos + recv_len - 1) / 8; @@ -1038,6 +1047,9 @@ static int is_reasm_buf_complete(const u_int8_t *buffer_bitmap, const u_int32_t remaining_bits = buffer_len % 8; u_int32_t i; + if (!buffer_bitmap) + return 0; + for(i = 0; i < complete_bytes; i++) if (buffer_bitmap[i] != 0xff) return 0; @@ -1058,7 +1070,8 @@ static int __reassemble(struct ndpi_flow_struct *flow, const u_int8_t *frag, if(!flow->l4.udp.quic_reasm_buf) { flow->l4.udp.quic_reasm_buf = (uint8_t *)ndpi_malloc(max_quic_reasm_buffer_len); - flow->l4.udp.quic_reasm_buf_bitmap = (uint8_t *)ndpi_calloc(quic_reasm_buffer_bitmap_len, sizeof(uint8_t)); + if(!flow->l4.udp.quic_reasm_buf_bitmap) + flow->l4.udp.quic_reasm_buf_bitmap = (uint8_t *)ndpi_calloc(quic_reasm_buffer_bitmap_len, sizeof(uint8_t)); if(!flow->l4.udp.quic_reasm_buf || !flow->l4.udp.quic_reasm_buf_bitmap) return -1; /* Memory error */ flow->l4.udp.quic_reasm_buf_last_pos = 0; diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index e8ce0ea97..05b03d98c 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -146,8 +146,8 @@ static u_int32_t __get_master(struct ndpi_detection_module_struct *ndpi_struct, /* **************************************** */ -void ndpi_search_tls_tcp_memory(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) { +int ndpi_search_tls_tcp_memory(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; message_t *message = &flow->l4.tcp.tls.message[packet->packet_direction]; u_int avail_bytes; @@ -166,7 +166,7 @@ void ndpi_search_tls_tcp_memory(struct ndpi_detection_module_struct *ndpi_struct message->buffer = (u_int8_t*)ndpi_malloc(message->buffer_len); if(message->buffer == NULL) - return; + return -1; #ifdef DEBUG_TLS_MEMORY printf("[TLS Mem] Allocating %u buffer\n", message->buffer_len); @@ -179,7 +179,7 @@ void ndpi_search_tls_tcp_memory(struct ndpi_detection_module_struct *ndpi_struct u_int new_len = message->buffer_len + packet->payload_packet_len - avail_bytes + 1; void *newbuf = ndpi_realloc(message->buffer, message->buffer_len, new_len); - if(!newbuf) return; + if(!newbuf) return -1; #ifdef DEBUG_TLS_MEMORY printf("[TLS Mem] Enlarging %u -> %u buffer\n", message->buffer_len, new_len); @@ -223,6 +223,7 @@ void ndpi_search_tls_tcp_memory(struct ndpi_detection_module_struct *ndpi_struct #endif } } + return 0; } /* **************************************** */ @@ -973,7 +974,8 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct, return 1; /* Keep working */ } - ndpi_search_tls_tcp_memory(ndpi_struct, flow); + if(ndpi_search_tls_tcp_memory(ndpi_struct, flow) == -1) + return 0; /* Error -> stop */ message = &flow->l4.tcp.tls.message[packet->packet_direction]; /* Valid TLS Content Types: @@ -2248,14 +2250,15 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, #endif if(flow->protos.tls_quic.advertised_alpns == NULL) { flow->protos.tls_quic.advertised_alpns = ndpi_strdup(alpn_str); + if(flow->protos.tls_quic.advertised_alpns) { + tlsCheckUncommonALPN(ndpi_struct, flow, flow->protos.tls_quic.advertised_alpns); - tlsCheckUncommonALPN(ndpi_struct, flow, flow->protos.tls_quic.advertised_alpns); - - /* Without SNI matching we can try to sub-classify the flow via ALPN. - Note that this happens only on very rare cases, not the common ones - ("h2", "http/1.1", ...). Usefull for asymmetric traffic */ - if(!flow->protos.tls_quic.subprotocol_detected) - tls_subclassify_by_alpn(ndpi_struct, flow); + /* Without SNI matching we can try to sub-classify the flow via ALPN. + Note that this happens only on very rare cases, not the common ones + ("h2", "http/1.1", ...). Usefull for asymmetric traffic */ + if(!flow->protos.tls_quic.subprotocol_detected) + tls_subclassify_by_alpn(ndpi_struct, flow); + } } alpn_str_len = ndpi_min(sizeof(ja3.client.alpn), (size_t)alpn_str_len); diff --git a/src/lib/third_party/src/libcache.c b/src/lib/third_party/src/libcache.c index 841ed160e..b7cee569e 100644 --- a/src/lib/third_party/src/libcache.c +++ b/src/lib/third_party/src/libcache.c @@ -161,6 +161,11 @@ cache_result cache_add(cache_t cache, void *item, uint32_t item_size) { entry->item = ndpi_malloc(item_size); + if(!entry->item) { + ndpi_free(entry); + ndpi_free(map_entry); + return CACHE_MALLOC_ERROR; + } memcpy(entry->item, item, item_size); entry->item_size = item_size; |