aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Nardi <12729895+IvanNardi@users.noreply.github.com>2022-12-06 17:41:58 +0100
committerGitHub <noreply@github.com>2022-12-06 17:41:58 +0100
commitada4fe4aa8f88300cfc0dbe6ee965975274b1c40 (patch)
tree08010d2055d0159330ded8e5c15113deb0c41c3b
parent946c3dba0f6c393c2e41b98103cec3e7308fbf2c (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--.gitignore4
-rw-r--r--example/reader_util.c32
-rw-r--r--fuzz/Makefile.am22
-rw-r--r--fuzz/fuzz_ndpi_reader.c33
-rw-r--r--src/lib/ndpi_analyze.c37
-rw-r--r--src/lib/ndpi_main.c7
-rw-r--r--src/lib/ndpi_serializer.c4
-rw-r--r--src/lib/ndpi_utils.c3
-rw-r--r--src/lib/protocols/quic.c23
-rw-r--r--src/lib/protocols/tls.c27
-rw-r--r--src/lib/third_party/src/libcache.c5
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;