Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fuzz: improve fuzzing coverage #2474

Merged
merged 1 commit into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example/reader_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1353,7 +1353,7 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl
flow->detected_protocol,
&flow->ndpi_flow_serializer) != 0) {
LOG(NDPI_LOG_ERROR, "flow2json failed\n");
exit(-1);
return;
}

ndpi_serialize_string_uint32(&flow->ndpi_flow_serializer, "detection_completed", flow->detection_completed);
Expand Down
Binary file not shown.
16 changes: 13 additions & 3 deletions fuzz/fuzz_alg_shoco.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
#include <stdint.h>
#include "shoco.h"
#include "ndpi_api.h"
#include "fuzzer/FuzzedDataProvider.h"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
FuzzedDataProvider fuzzed_data(data, size);
const char *in;
size_t in_len, out_len;
char out[8192], orig[8192];
int higher_level_api;

/* No memory allocations involved */

higher_level_api = fuzzed_data.ConsumeBool();

std::string s = fuzzed_data.ConsumeRemainingBytesAsString().c_str();
in = s.c_str();
in_len = strlen(in);

out_len = shoco_compress(in, in_len, out, sizeof(out));
if(out_len <= sizeof(out)) /* No error */
shoco_decompress(out, out_len, orig, sizeof(orig));
if(!higher_level_api) {
out_len = shoco_compress(in, in_len, out, sizeof(out));
if(out_len <= sizeof(out)) /* No error */
shoco_decompress(out, out_len, orig, sizeof(orig));
} else {
out_len = ndpi_compress_str(in, in_len, out, sizeof(out));
if(out_len != 0) /* No error */
ndpi_decompress_str(out, out_len, orig, sizeof(orig));
}

return 0;
}
7 changes: 6 additions & 1 deletion fuzz/fuzz_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
ndpi_severity2str(static_cast<ndpi_risk_severity>(fuzzed_data.ConsumeIntegral<u_int8_t>()));
ndpi_risk2score(static_cast<ndpi_risk_enum>(fuzzed_data.ConsumeIntegral<u_int64_t>()), &unused1, &unused2);
ndpi_http_method2str(static_cast<ndpi_http_method>(fuzzed_data.ConsumeIntegral<u_int8_t>()));
ndpi_confidence_get_name(static_cast<ndpi_confidence_t>(fuzzed_data.ConsumeIntegral<u_int8_t>()));
ndpi_get_proto_breed_name(static_cast<ndpi_protocol_breed_t>(fuzzed_data.ConsumeIntegral<u_int8_t>()));
ndpi_get_l4_proto_name(static_cast<ndpi_l4_proto_info>(fuzzed_data.ConsumeIntegral<u_int8_t>()));

char buf2[16];
ndpi_entropy2str(fuzzed_data.ConsumeFloatingPoint<float>(), fuzzed_data.ConsumeBool() ? buf2 : NULL, sizeof(buf2));

/* Basic code to try testing this "config" */
bool_value = fuzzed_data.ConsumeBool();
Expand Down Expand Up @@ -545,7 +551,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
ndpi_get_flow_ndpi_proto(&flow, &p2);
ndpi_is_proto(p, NDPI_PROTOCOL_TLS);
ndpi_http_method2str(flow.http.method);
ndpi_get_l4_proto_name(ndpi_get_l4_proto_info(ndpi_info_mod, p.app_protocol));
ndpi_is_subprotocol_informative(p.app_protocol);
ndpi_get_http_method(bool_value ? &flow : NULL);
ndpi_get_http_url(&flow);
Expand Down
5 changes: 4 additions & 1 deletion fuzz/fuzz_ds_ahocorasick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
ac_automata_enable_debug(0);

a = ac_automata_init(mc);
a2 = ndpi_init_automa();
if (fuzzed_data.ConsumeBool())
a2 = ndpi_init_automa();
else
a2 = ndpi_init_automa_domain();

if (fuzzed_data.ConsumeBool())
ac_automata_feature(a, AC_FEATURE_DEBUG);
Expand Down
2 changes: 1 addition & 1 deletion fuzz/fuzz_ds_domain_classify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
num_iteration = fuzzed_data.ConsumeIntegral<u_int8_t>();
for (i = 0; i < num_iteration; i++) {
value = fuzzed_data.ConsumeBytesAsString(fuzzed_data.ConsumeIntegral<u_int8_t>());
ndpi_domain_classify_hostname(ndpi_struct, d, &class_id, (char *)value.c_str());
ndpi_domain_classify_hostname(fuzzed_data.ConsumeBool() ? ndpi_struct : NULL, d, &class_id, (char *)value.c_str());
}

/* Search of an added entry */
Expand Down
8 changes: 8 additions & 0 deletions fuzz/fuzz_gcrypt_cipher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define MBEDTLS_CHECK_RETURN_TYPICAL
#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) do { } while( 0 )
#include "gcrypt/cipher.h"
#include "gcrypt/error.h"
#include "gcrypt/aes.h"

extern int force_no_aesni;
Expand Down Expand Up @@ -56,10 +57,17 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
mbedtls_cipher_info_get_type(ctx_e->cipher_info);
mbedtls_cipher_info_get_name(ctx_e->cipher_info);
mbedtls_cipher_info_has_variable_key_bitlen(ctx_e->cipher_info);
mbedtls_cipher_info_has_variable_iv_size(ctx_e->cipher_info);
mbedtls_cipher_info_get_iv_size(ctx_e->cipher_info);
mbedtls_cipher_info_get_block_size(ctx_e->cipher_info);
mbedtls_cipher_get_cipher_mode(ctx_e);
mbedtls_cipher_get_iv_size(ctx_e);
mbedtls_cipher_get_type(ctx_e);
mbedtls_cipher_get_name(ctx_e);
mbedtls_cipher_get_key_bitlen(ctx_e);
mbedtls_cipher_get_operation(ctx_e);
mbedtls_cipher_info_get_key_bitlen(ctx_e->cipher_info);
mbedtls_error_add(0, 0, NULL, 0);

posix_memalign((void **)&ctx_e->cipher_ctx, 8, sizeof(mbedtls_aes_context));
posix_memalign((void **)&ctx_d->cipher_ctx, 8, sizeof(mbedtls_aes_context));
Expand Down
6 changes: 5 additions & 1 deletion fuzz/fuzz_ndpi_reader.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct ndpi_global_context *g_ctx;
u_int8_t enable_payload_analyzer = 0;
u_int8_t enable_flow_stats = 1;
u_int8_t human_readeable_string_len = 5;
u_int8_t max_num_udp_dissected_pkts = 16 /* 8 is enough for most protocols, Signal requires more */, max_num_tcp_dissected_pkts = 80 /* due to telnet */;
u_int8_t max_num_udp_dissected_pkts = 0, max_num_tcp_dissected_pkts = 0; /* Disable limits at application layer */;
int malloc_size_stats = 0;

extern void ndpi_report_payload_stats(FILE *out);
Expand Down Expand Up @@ -53,6 +53,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {

workflow = ndpi_workflow_init(prefs, NULL /* pcap handler will be set later */, 0, ndpi_serialization_format_json, g_ctx);

ndpi_workflow_set_flow_callback(workflow, NULL, NULL); /* No real callback */

ndpi_set_config(workflow->ndpi_struct, NULL, "log.level", "3");
ndpi_set_config(workflow->ndpi_struct, "all", "log", "1");

Expand All @@ -68,10 +70,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
NDPI_BITMASK_SET_ALL(all);
ndpi_set_protocol_detection_bitmask2(workflow->ndpi_struct, &all);

ndpi_set_config(workflow->ndpi_struct, NULL, "packets_limit_per_flow", "255");
ndpi_set_config(workflow->ndpi_struct, NULL, "flow.track_payload", "1");
ndpi_set_config(workflow->ndpi_struct, NULL, "tcp_ack_payload_heuristic", "1");
ndpi_set_config(workflow->ndpi_struct, "tls", "application_blocks_tracking", "1");
ndpi_set_config(workflow->ndpi_struct, "stun", "max_packets_extra_dissection", "255");
ndpi_set_config(workflow->ndpi_struct, "zoom", "max_packets_extra_dissection", "255");
ndpi_set_config(workflow->ndpi_struct, "rtp", "search_for_stun", "1");

ndpi_finalize_initialization(workflow->ndpi_struct);
Expand Down
24 changes: 14 additions & 10 deletions fuzz/fuzz_serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
int rc;
std::vector<char>d;
char kbuf[32];
u_int32_t buffer_len;
u_int32_t buffer_len, kbuf_len;

/* To allow memory allocation failures */
fuzz_set_alloc_callbacks_and_seed(size);
Expand Down Expand Up @@ -66,19 +66,23 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
ndpi_serialize_string_raw(&serializer, kbuf, d.data(), d.size());
ndpi_serialize_string_boolean(&serializer, kbuf, fuzzed_data.ConsumeIntegral<int8_t>());

if (fuzzed_data.ConsumeBool())
if (fuzzed_data.ConsumeBool()) {
snprintf(kbuf, sizeof(kbuf), "%d", i); /* To trigger OPTIMIZE_NUMERIC_KEYS */
ndpi_serialize_binary_uint32(&serializer, kbuf, sizeof(kbuf), fuzzed_data.ConsumeIntegral<u_int32_t>());
ndpi_serialize_binary_int32(&serializer, kbuf, sizeof(kbuf), fuzzed_data.ConsumeIntegral<int32_t>());
ndpi_serialize_binary_uint64(&serializer, kbuf, sizeof(kbuf), fuzzed_data.ConsumeIntegral<u_int64_t>());
ndpi_serialize_binary_int64(&serializer, kbuf, sizeof(kbuf), fuzzed_data.ConsumeIntegral<int64_t>());
ndpi_serialize_binary_float(&serializer, kbuf, sizeof(kbuf), fuzzed_data.ConsumeFloatingPoint<float>(), "%f");
kbuf_len = strlen(kbuf);
} else {
kbuf_len = sizeof(kbuf);
}
ndpi_serialize_binary_uint32(&serializer, kbuf, kbuf_len, fuzzed_data.ConsumeIntegral<u_int32_t>());
ndpi_serialize_binary_int32(&serializer, kbuf, kbuf_len, fuzzed_data.ConsumeIntegral<int32_t>());
ndpi_serialize_binary_uint64(&serializer, kbuf, kbuf_len, fuzzed_data.ConsumeIntegral<u_int64_t>());
ndpi_serialize_binary_int64(&serializer, kbuf, kbuf_len, fuzzed_data.ConsumeIntegral<int64_t>());
ndpi_serialize_binary_float(&serializer, kbuf, kbuf_len, fuzzed_data.ConsumeFloatingPoint<float>(), "%f");
if (fmt != ndpi_serialization_format_tlv)
ndpi_serialize_binary_double(&serializer, kbuf, sizeof(kbuf), fuzzed_data.ConsumeFloatingPoint<double>(), "%lf");
ndpi_serialize_binary_boolean(&serializer, kbuf, sizeof(kbuf), fuzzed_data.ConsumeIntegral<int8_t>());
ndpi_serialize_binary_double(&serializer, kbuf, kbuf_len, fuzzed_data.ConsumeFloatingPoint<double>(), "%lf");
ndpi_serialize_binary_boolean(&serializer, kbuf, kbuf_len, fuzzed_data.ConsumeIntegral<int8_t>());
d = fuzzed_data.ConsumeBytes<char>(16);
if (d.size())
ndpi_serialize_binary_binary(&serializer, kbuf, sizeof(kbuf), d.data(), d.size());
ndpi_serialize_binary_binary(&serializer, kbuf, kbuf_len, d.data(), d.size());

if ((i & 0x3) == 0x3)
ndpi_serialize_end_of_record(&serializer);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/ndpi_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4976,7 +4976,7 @@ int load_category_file_fd(struct ndpi_detection_module_struct *ndpi_str,
continue;
}

if(ndpi_load_category(ndpi_str, line, category_id, NULL) > 0)
if(ndpi_load_category(ndpi_str, line, category_id, NULL) >= 0)
num_loaded++;
}

Expand Down
14 changes: 0 additions & 14 deletions src/lib/protocols/afp.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,6 @@ static void ndpi_search_afp(struct ndpi_detection_module_struct *ndpi_struct, st
return;
}

/*
* this will detect the OpenSession command of the Data Stream Interface (DSI) protocol
* which is exclusively used by the Apple Filing Protocol (AFP) on TCP/IP networks
*/
if (packet->payload_packet_len >= 22 && get_u_int16_t(packet->payload, 0) == htons(0x0004) &&
get_u_int16_t(packet->payload, 2) == htons(0x0001) && get_u_int32_t(packet->payload, 4) == 0 &&
get_u_int32_t(packet->payload, 8) == htonl(packet->payload_packet_len - 16) &&
get_u_int32_t(packet->payload, 12) == 0 && get_u_int16_t(packet->payload, 16) == htons(0x0104)) {

NDPI_LOG_INFO(ndpi_struct, "found AFP: DSI OpenSession\n");
ndpi_int_afp_add_connection(ndpi_struct, flow);
return;
}

if((h->flags <= 1)
&& ((h->command >= 1) && (h->command <= 8))
&& (h->reserved == 0)
Expand Down
9 changes: 2 additions & 7 deletions src/lib/protocols/mqtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,18 +179,13 @@ static void ndpi_search_mqtt(struct ndpi_detection_module_struct *ndpi_struct,
}
if (pt == PUBLISH) {
// payload CAN be zero bytes length (section 3.3.3 of MQTT standard)
u_int8_t qos = (u_int8_t) (flags & 0x06);
u_int8_t dup = (u_int8_t) (flags & 0x04);
u_int8_t qos = (u_int8_t) (flags & 0x06) >> 1;
u_int8_t dup = (u_int8_t) (flags & 0x08) >> 3;
if (qos > 2) { // qos values possible are 0,1,2
NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt invalid PUBLISH qos\n");
NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
return;
}
if (dup > 1) { // dup flag possible 0,1
NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt invalid PUBLISH dup\n");
NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MQTT);
return;
}
if (qos == 0) {
if (dup != 0) {
NDPI_LOG_DBG(ndpi_struct, "Excluding Mqtt invalid PUBLISH qos0 and dup combination\n");
Expand Down
5 changes: 1 addition & 4 deletions src/lib/protocols/ssdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,7 @@ static void ssdp_parse_lines(struct ndpi_detection_module_struct

/* Save host which provides a service if available */
if (packet->host_line.ptr != NULL && packet->host_line.len > 0) {
if (ndpi_hostname_sni_set(flow, packet->host_line.ptr, packet->host_line.len, NDPI_HOSTNAME_NORM_ALL) == NULL)
{
NDPI_LOG_DBG2(ndpi_struct, "Could not set SSDP host\n");
}
ndpi_hostname_sni_set(flow, packet->host_line.ptr, packet->host_line.len, NDPI_HOSTNAME_NORM_ALL);
}
}

Expand Down
3 changes: 0 additions & 3 deletions src/lib/protocols/thrift.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,6 @@ static void ndpi_int_thrift_add_connection(struct ndpi_detection_module_struct *
case NDPI_PROTOCOL_HTTP:
NDPI_LOG_DBG(ndpi_struct, "found Apache Thrift HTTP\n");
break;
default:
NDPI_LOG_DBG(ndpi_struct, "found Apache Thrift\n");
break;
}

ndpi_set_detected_protocol(ndpi_struct, flow,
Expand Down
5 changes: 0 additions & 5 deletions src/lib/protocols/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1032,10 +1032,6 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct,
break;
}

if(len == 0) {
something_went_wrong = 1;
break;
}

#ifdef DEBUG_TLS_MEMORY
printf("[TLS Mem] Processing %u bytes message\n", len);
Expand Down Expand Up @@ -1638,7 +1634,6 @@ static bool is_grease_version(u_int16_t version) {
case 0xeaea:
case 0xfafa:
return(true);
break;

default:
return(false);
Expand Down
Binary file modified tests/cfgs/default/pcap/netbios.pcap
Binary file not shown.
Binary file added tests/cfgs/default/pcap/pgsql2.pcapng
Binary file not shown.
Loading
Loading