aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--fuzz/Makefile.am17
-rw-r--r--fuzz/fuzz_ds_address_cache.cpp106
-rw-r--r--src/lib/ndpi_cache.c24
4 files changed, 140 insertions, 8 deletions
diff --git a/.gitignore b/.gitignore
index 8ef05eb83..f94473adf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -82,6 +82,7 @@
/fuzz/fuzz_ds_domain_classify
/fuzz/fuzz_ds_kdtree
/fuzz/fuzz_ds_btree
+/fuzz/fuzz_ds_address_cache
/fuzz/fuzz_libinjection
/fuzz/fuzz_binaryfusefilter
/fuzz/fuzz_tls_certificate
diff --git a/fuzz/Makefile.am b/fuzz/Makefile.am
index 30ce2d969..273464d29 100644
--- a/fuzz/Makefile.am
+++ b/fuzz/Makefile.am
@@ -2,7 +2,7 @@ bin_PROGRAMS = fuzz_process_packet fuzz_ndpi_reader fuzz_ndpi_reader_alloc_fail
#Alghoritms
bin_PROGRAMS += fuzz_alg_bins fuzz_alg_hll fuzz_alg_hw_rsi_outliers_da fuzz_alg_jitter fuzz_alg_ses_des fuzz_alg_crc32_md5 fuzz_alg_bytestream fuzz_alg_shoco fuzz_alg_memmem fuzz_alg_strnstr fuzz_alg_quick_encryption
#Data structures
-bin_PROGRAMS += fuzz_ds_patricia fuzz_ds_ahocorasick fuzz_ds_libcache fuzz_ds_tree fuzz_ds_ptree fuzz_ds_hash fuzz_ds_cmsketch fuzz_ds_bitmap64_fuse fuzz_ds_domain_classify fuzz_ds_kdtree fuzz_ds_btree
+bin_PROGRAMS += fuzz_ds_patricia fuzz_ds_ahocorasick fuzz_ds_libcache fuzz_ds_tree fuzz_ds_ptree fuzz_ds_hash fuzz_ds_cmsketch fuzz_ds_bitmap64_fuse fuzz_ds_domain_classify fuzz_ds_kdtree fuzz_ds_btree fuzz_ds_address_cache
#Third party
bin_PROGRAMS += fuzz_libinjection fuzz_binaryfusefilter
#Internal crypto
@@ -444,6 +444,21 @@ fuzz_ds_btree_LINK=$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXX) @NDPI_CFLAGS@ $(AM_CXXFLAGS) $(CXXFLAGS) \
$(fuzz_ds_btree_LDFLAGS) @NDPI_LDFLAGS@ $(LDFLAGS) -o $@
+fuzz_ds_address_cache_SOURCES = fuzz_ds_address_cache.cpp fuzz_common_code.c
+fuzz_ds_address_cache_CXXFLAGS = @NDPI_CFLAGS@ $(CXXFLAGS) -DNDPI_LIB_COMPILATION
+fuzz_ds_address_cache_CFLAGS = @NDPI_CFLAGS@ $(CXXFLAGS) -DNDPI_LIB_COMPILATION
+fuzz_ds_address_cache_LDADD = ../src/lib/libndpi.a $(ADDITIONAL_LIBS)
+fuzz_ds_address_cache_LDFLAGS = $(LIBS)
+if HAS_FUZZLDFLAGS
+fuzz_ds_address_cache_CXXFLAGS += $(LIB_FUZZING_ENGINE)
+fuzz_ds_address_cache_CFLAGS += $(LIB_FUZZING_ENGINE)
+fuzz_ds_address_cache_LDFLAGS += $(LIB_FUZZING_ENGINE)
+endif
+# force usage of CXX for linker
+fuzz_ds_address_cache_LINK=$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXX) @NDPI_CFLAGS@ $(AM_CXXFLAGS) $(CXXFLAGS) \
+ $(fuzz_ds_address_cache_LDFLAGS) @NDPI_LDFLAGS@ $(LDFLAGS) -o $@
+
fuzz_libinjection_SOURCES = fuzz_libinjection.c
fuzz_libinjection_CFLAGS = @NDPI_CFLAGS@ $(CXXFLAGS)
fuzz_libinjection_LDADD = ../src/lib/libndpi.a $(ADDITIONAL_LIBS)
diff --git a/fuzz/fuzz_ds_address_cache.cpp b/fuzz/fuzz_ds_address_cache.cpp
new file mode 100644
index 000000000..4bef64fe9
--- /dev/null
+++ b/fuzz/fuzz_ds_address_cache.cpp
@@ -0,0 +1,106 @@
+#include "ndpi_api.h"
+#include "ndpi_private.h"
+
+#include "fuzz_common_code.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+#include "fuzzer/FuzzedDataProvider.h"
+
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ FuzzedDataProvider fuzzed_data(data, size);
+ u_int16_t i, num_iteration;
+ int is_added = 0;
+ struct ndpi_detection_module_struct ndpi_struct; /*Opaque; we don't really need to initialize it */
+ ndpi_ip_addr_t ip_addr, ip_addr_added;
+ char *hostname, *hostname2;
+ u_int32_t epoch_now;
+ u_int32_t ttl;
+ bool rc;
+ char path[] = "random.dump";
+
+
+ /* Just to have some data */
+ if (fuzzed_data.remaining_bytes() < 1024)
+ return -1;
+
+ /* To allow memory allocation failures */
+ fuzz_set_alloc_callbacks_and_seed(size);
+
+
+ memset(&ndpi_struct, '\0', sizeof(struct ndpi_detection_module_struct));
+ ndpi_struct.cfg.address_cache_size = fuzzed_data.ConsumeIntegral<u_int8_t>();
+
+ epoch_now = 1;
+
+ /* Random insert */
+ num_iteration = fuzzed_data.ConsumeIntegral<u_int8_t>();
+ for (i = 0; i < num_iteration; i++) {
+ if (fuzzed_data.ConsumeBool()) {
+ if(fuzzed_data.remaining_bytes() > 16) {
+ memcpy(&ip_addr.ipv6, fuzzed_data.ConsumeBytes<u_int8_t>(16).data(), 16);
+ } else {
+ continue;
+ }
+ } else {
+ memset(&ip_addr, '\0', sizeof(ip_addr));
+ ip_addr.ipv4 = fuzzed_data.ConsumeIntegral<u_int32_t>();
+ }
+ hostname = strdup(fuzzed_data.ConsumeRandomLengthString(32).c_str());
+ ttl = fuzzed_data.ConsumeIntegral<u_int8_t>();
+ epoch_now += fuzzed_data.ConsumeIntegral<u_int8_t>();
+
+ rc = ndpi_cache_address(&ndpi_struct, ip_addr, hostname, epoch_now, ttl);
+ if (rc == true) {
+ if(is_added == 0 && fuzzed_data.ConsumeBool()) {
+ /* Keep one random node really added */
+ is_added = 1;
+ ip_addr_added = ip_addr;
+ } else if(fuzzed_data.ConsumeBool()) {
+ /* Add also same ip with different hostname */
+ hostname2 = ndpi_strdup(fuzzed_data.ConsumeRandomLengthString(32).c_str());
+ ndpi_cache_address(&ndpi_struct, ip_addr, hostname2, epoch_now, ttl);
+ ndpi_free(hostname2);
+ }
+ }
+ ndpi_free(hostname);
+ }
+
+ /* "Random" search */
+ num_iteration = fuzzed_data.ConsumeIntegral<u_int8_t>();
+ for (i = 0; i < num_iteration; i++) {
+ if (fuzzed_data.ConsumeBool()) {
+ if(fuzzed_data.remaining_bytes() > 16) {
+ memcpy(&ip_addr.ipv6, fuzzed_data.ConsumeBytes<u_int8_t>(16).data(), 16);
+ } else {
+ continue;
+ }
+ } else {
+ memset(&ip_addr, '\0', sizeof(ip_addr));
+ ip_addr.ipv4 = fuzzed_data.ConsumeIntegral<u_int32_t>();
+ }
+
+ ndpi_cache_address_find(&ndpi_struct, ip_addr);
+ }
+ /* Search of an added entry */
+ if(is_added)
+ ndpi_cache_address_find(&ndpi_struct, ip_addr_added);
+
+ if(fuzzed_data.ConsumeBool()) {
+ epoch_now += fuzzed_data.ConsumeIntegral<u_int8_t>();
+ ndpi_cache_address_flush_expired(&ndpi_struct, epoch_now);
+ }
+
+ epoch_now += fuzzed_data.ConsumeIntegral<u_int8_t>();
+ rc = ndpi_cache_address_dump(&ndpi_struct, path, epoch_now);
+ if(rc) {
+ epoch_now += fuzzed_data.ConsumeIntegral<u_int8_t>();
+ ndpi_cache_address_restore(&ndpi_struct, path, epoch_now);
+ }
+
+ ndpi_term_address_cache(ndpi_struct.address_cache);
+
+ return 0;
+}
diff --git a/src/lib/ndpi_cache.c b/src/lib/ndpi_cache.c
index 632b31487..c4e25ffea 100644
--- a/src/lib/ndpi_cache.c
+++ b/src/lib/ndpi_cache.c
@@ -221,7 +221,7 @@ struct ndpi_address_cache* ndpi_init_address_cache(u_int32_t max_num_entries) {
ret->num_cached_addresses = 0, ret->num_entries = 0,
ret->max_num_entries = max_num_entries,
- ret->num_root_nodes = ndpi_min(NDPI_NUM_DEFAULT_ROOT_NODES, max_num_entries/16);
+ ret->num_root_nodes = ndpi_max(1, ndpi_min(NDPI_NUM_DEFAULT_ROOT_NODES, max_num_entries/16));
ret->address_cache_root = (struct ndpi_address_cache_item**)ndpi_calloc(ret->num_root_nodes, sizeof(struct ndpi_address_cache_item*));
if(ret->address_cache_root == NULL) {
@@ -243,6 +243,9 @@ static void ndpi_free_addr_item(struct ndpi_address_cache_item *addr) {
void ndpi_term_address_cache(struct ndpi_address_cache *cache) {
u_int i;
+ if(!cache)
+ return;
+
for(i=0; i<cache->num_root_nodes; i++) {
struct ndpi_address_cache_item *root = cache->address_cache_root[i];
@@ -323,8 +326,10 @@ struct ndpi_address_cache_item* ndpi_address_cache_find(struct ndpi_address_cach
if(memcmp(&root->addr, &ip_addr, sizeof(ndpi_ip_addr_t)) == 0) {
return(root);
- } else
+ } else {
+ prev = root;
root = root->next;
+ }
}
return(NULL);
@@ -340,6 +345,9 @@ bool ndpi_address_cache_insert(struct ndpi_address_cache *cache,
struct ndpi_address_cache_item *ret;
u_int32_t epoch_valid_until;
+ if(!hostname)
+ return(false);
+
if(epoch_now == 0) epoch_now = (u_int32_t)time(NULL);
ret = ndpi_address_cache_find(cache, ip_addr, epoch_now);
epoch_valid_until = epoch_now + ttl;
@@ -366,13 +374,13 @@ bool ndpi_address_cache_insert(struct ndpi_address_cache *cache,
ret->expire_epoch = epoch_valid_until,
ret->next = cache->address_cache_root[hash_id];
- /* Create linked list */
- cache->address_cache_root[hash_id] = ret;
-
- if((ret->hostname = strdup(hostname)) == NULL) {
+ if((ret->hostname = ndpi_strdup(hostname)) == NULL) {
ndpi_free(ret);
return(false);
}
+
+ /* Create linked list */
+ cache->address_cache_root[hash_id] = ret;
} else {
/* Element found: update TTL of the existing element */
ret->expire_epoch = ndpi_max(ret->expire_epoch, epoch_valid_until);
@@ -410,8 +418,10 @@ bool ndpi_address_cache_dump(struct ndpi_address_cache *cache,
u_char *a = (u_char*)&(root->addr);
u_int j, idx;
- if(epoch_now && (root->expire_epoch < epoch_now))
+ if(epoch_now && (root->expire_epoch < epoch_now)) {
+ root = root->next;
continue; /* Expired epoch */
+ }
for(j=0, idx=0; j<sizeof(ndpi_ip_addr_t); j++, idx += 2)
snprintf(&buf[idx], sizeof(buf)-idx, "%02X", a[j]);