diff options
author | Nardi Ivan <nardi.ivan@gmail.com> | 2023-02-23 14:33:41 +0100 |
---|---|---|
committer | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2023-03-01 20:34:56 +0100 |
commit | 9eb9664516aafb821097f049717c70e576ac18a6 (patch) | |
tree | 8e9c884f9e8854501fa3bfefd03e93031ffb5a16 /src/lib/protocols/softether.c | |
parent | 127d8d0d352206d2fa3191a30a7491b3b1f3da00 (diff) |
SoftEther: fix invalid memory access
We can't write `flow->protos` union until we are really sure about protocol
classification
```
==28334==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x558db5554512 bp 0x000000000000 sp 0x7ffcb22c2880 T0)
==28334==The signal is caused by a READ memory access.
==28334==Hint: this fault was caused by a dereference of a high value address (see register values below). Disassemble the provided pc to learn which register was used.
#0 0x558db5554512 in __asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) (/home/ivan/svnrepos/nDPI/fuzz/fuzz_process_packet+0x48e512) (BuildId: 2f71e395637a7b748f36d5a04c7281f18b1128d7)
#1 0x558db55ea54b in __interceptor_free (/home/ivan/svnrepos/nDPI/fuzz/fuzz_process_packet+0x52454b) (BuildId: 2f71e395637a7b748f36d5a04c7281f18b1128d7)
#2 0x558db56977ca in ndpi_free /home/ivan/svnrepos/nDPI/src/lib/ndpi_main.c:274:7
#3 0x558db56c20e3 in ndpi_free_flow_data /home/ivan/svnrepos/nDPI/src/lib/ndpi_main.c:5175:2
#4 0x558db569783f in ndpi_free_flow /home/ivan/svnrepos/nDPI/src/lib/ndpi_main.c:8394:5
#5 0x558db5627936 in LLVMFuzzerTestOneInput /home/ivan/svnrepos/nDPI/fuzz/fuzz_process_packet.c:38:3
```
Found by oss-fuzz
See: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=56272
Diffstat (limited to 'src/lib/protocols/softether.c')
-rw-r--r-- | src/lib/protocols/softether.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/src/lib/protocols/softether.c b/src/lib/protocols/softether.c index 5992ec322..3c90b0da9 100644 --- a/src/lib/protocols/softether.c +++ b/src/lib/protocols/softether.c @@ -177,9 +177,10 @@ static int dissect_softether_host_fqdn(struct ndpi_flow_struct *flow, u_int8_t const *payload = packet->payload; u_int16_t payload_len = packet->payload_packet_len; u_int32_t tuple_count; - size_t value_siz; + size_t value_siz, hostname_len, fqdn_len; struct softether_value val1, val2; uint8_t got_hostname = 0, got_fqdn = 0; + const char *hostname_ptr = NULL, *fqdn_ptr = NULL; if(payload_len < 4) return 1; @@ -208,20 +209,16 @@ static int dissect_softether_host_fqdn(struct ndpi_flow_struct *flow, if(got_hostname == 1) { if(val1.type == VALUE_STR && val1.value_size > 0) { - size_t len = ndpi_min(val1.value_size, sizeof(flow->protos.softether.hostname) - 1); - - strncpy(flow->protos.softether.hostname, val1.value.ptr.value_str, len); - flow->protos.softether.hostname[len] = '\0'; + hostname_len = ndpi_min(val1.value_size, sizeof(flow->protos.softether.hostname) - 1); + hostname_ptr = val1.value.ptr.value_str; } got_hostname = 0; } if(got_fqdn == 1) { if(val1.type == VALUE_STR && val1.value_size > 0) { - size_t len = ndpi_min(val1.value_size, sizeof(flow->protos.softether.fqdn) - 1); - - strncpy(flow->protos.softether.fqdn, val1.value.ptr.value_str, len); - flow->protos.softether.fqdn[len] = '\0'; + fqdn_len = ndpi_min(val1.value_size, sizeof(flow->protos.softether.fqdn) - 1); + fqdn_ptr = val1.value.ptr.value_str; } got_fqdn = 0; @@ -239,6 +236,15 @@ static int dissect_softether_host_fqdn(struct ndpi_flow_struct *flow, if(payload_len != 0 || tuple_count != 0) return 1; + /* Ok, write to `flow->protos.softether` */ + if(hostname_ptr) { + strncpy(flow->protos.softether.hostname, hostname_ptr, hostname_len); + flow->protos.softether.hostname[hostname_len] = '\0'; + } + if(fqdn_ptr) { + strncpy(flow->protos.softether.fqdn, fqdn_ptr, fqdn_len); + flow->protos.softether.fqdn[fqdn_len] = '\0'; + } return 0; } @@ -308,7 +314,7 @@ static void ndpi_search_softether(struct ndpi_detection_module_struct *ndpi_stru return; } } - + if(packet->payload_packet_len >= 99) { if(dissect_softether_host_fqdn(flow, packet) == 0) { ndpi_int_softether_add_connection(ndpi_struct, flow); |