Skip to content
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
Binary file added fuzz/corpus/fuzz_dns_parse/issue3213_trigger1
Binary file not shown.
Binary file added fuzz/corpus/fuzz_dns_parse/issue3213_trigger2
Binary file not shown.
Binary file added fuzz/corpus/fuzz_dns_parse/issue3213_trigger3
Binary file not shown.
40 changes: 28 additions & 12 deletions src/include/ndpi_define.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -131,22 +131,38 @@

#define NDPI_ARRAY_LENGTH(array) (sizeof(array) / sizeof((array)[0]))

/* the get_uXX will return raw network packet bytes !! */
#define get_u_int8_t(X,O) (*(u_int8_t *)((&(((u_int8_t *)X)[O]))))
#define get_u_int16_t(X,O) (*(u_int16_t *)((&(((u_int8_t *)X)[O]))))
#define get_u_int32_t(X,O) (*(u_int32_t *)((&(((u_int8_t *)X)[O]))))
#if defined(__arm__)
/* The get_uXX helpers return raw network packet bytes. */
#ifndef NDPI_CFFI_PREPROCESSING
#include <stdint.h>
#include <string.h>
static inline uint64_t get_u_int64_t(const uint8_t* X, int O)

#define get_u_int8_t(X,O) (((const uint8_t *)(X))[O])

static inline uint16_t ndpi_get_u_int16_t(const void *X, int O)
{
uint64_t tmp;
memcpy(&tmp, X + O, sizeof(tmp));
return tmp;
uint16_t value;
memcpy(&value, ((const uint8_t *)X) + O, sizeof(value));
return value;
}
#else
#define get_u_int64_t(X,O) (*(u_int64_t *)((&(((u_int8_t *)X)[O]))))
#endif // __arm__

static inline uint32_t ndpi_get_u_int32_t(const void *X, int O)
{
uint32_t value;
memcpy(&value, ((const uint8_t *)X) + O, sizeof(value));
return value;
}

static inline uint64_t ndpi_get_u_int64_t(const void *X, int O)
{
uint64_t value;
memcpy(&value, ((const uint8_t *)X) + O, sizeof(value));
return value;
}

#define get_u_int16_t(X,O) ndpi_get_u_int16_t((X), (O))
#define get_u_int32_t(X,O) ndpi_get_u_int32_t((X), (O))
#define get_u_int64_t(X,O) ndpi_get_u_int64_t((X), (O))
#endif /* NDPI_CFFI_PREPROCESSING */

/* new definitions to get little endian from network bytes */
#define get_ul8(X,O) get_u_int8_t(X,O)
Expand Down
17 changes: 15 additions & 2 deletions src/include/ndpi_typedefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1543,10 +1543,23 @@ typedef struct {

#define ndpi_private_deserializer ndpi_private_serializer

/*
* The public serializer is opaque, but its storage is reinterpreted as
* ndpi_private_serializer by the implementation. Keep the private type as a
* union member so the public object carries the private type's alignment while
* retaining the existing character-buffer storage contract. The union member
* is the alignment guarantee; the assertion below protects the storage size.
*/
#ifdef NDPI_CFFI_PREPROCESSING
typedef struct { char c[72]; } ndpi_serializer;
typedef union { ndpi_private_serializer _alignment; char c[72]; } ndpi_serializer;
#else
typedef struct { char c[sizeof(ndpi_private_serializer)]; } ndpi_serializer;
typedef union { ndpi_private_serializer _alignment; char c[sizeof(ndpi_private_serializer)]; } ndpi_serializer;
Comment thread
IvanNardi marked this conversation as resolved.
#endif

#if !defined(NDPI_CFFI_PREPROCESSING) \
&& defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
_Static_assert(sizeof(ndpi_serializer) == sizeof(ndpi_private_serializer),
"ndpi_serializer storage size must match ndpi_private_serializer");
#endif

#define ndpi_deserializer ndpi_serializer
Expand Down
12 changes: 6 additions & 6 deletions src/lib/ndpi_serializer.c
Original file line number Diff line number Diff line change
Expand Up @@ -545,14 +545,14 @@ static inline void ndpi_deserialize_single_uint8(ndpi_private_deserializer *dese

static inline void ndpi_deserialize_single_uint16(ndpi_private_deserializer *deserializer,
u_int32_t offset, u_int16_t *s) {
*s = ntohs(*((u_int16_t *) &deserializer->buffer.data[offset]));
*s = ntohs(get_u_int16_t(deserializer->buffer.data, offset));
}

/* ********************************** */

static inline void ndpi_deserialize_single_uint32(ndpi_private_deserializer *deserializer,
u_int32_t offset, u_int32_t *s) {
*s = ntohl(*((u_int32_t *) &deserializer->buffer.data[offset]));
*s = ntohl(get_u_int32_t(deserializer->buffer.data, offset));
}

/* ********************************** */
Expand All @@ -566,28 +566,28 @@ static inline void ndpi_deserialize_single_int8(ndpi_private_deserializer *deser

static inline void ndpi_deserialize_single_int16(ndpi_private_deserializer *deserializer,
u_int32_t offset, int16_t *s) {
*s = ntohs(*((int16_t *) &deserializer->buffer.data[offset]));
*s = ntohs(get_u_int16_t(deserializer->buffer.data, offset));
}

/* ********************************** */

static inline void ndpi_deserialize_single_int32(ndpi_private_deserializer *deserializer,
u_int32_t offset, int32_t *s) {
*s = ntohl(*((int32_t *) &deserializer->buffer.data[offset]));
*s = ntohl(get_u_int32_t(deserializer->buffer.data, offset));
}

/* ********************************** */

static inline void ndpi_deserialize_single_uint64(ndpi_private_deserializer *deserializer,
u_int32_t offset, u_int64_t *s) {
*s = ndpi_ntohll(*(u_int64_t*)&deserializer->buffer.data[offset]);
*s = ndpi_ntohll(get_u_int64_t(deserializer->buffer.data, offset));
}

/* ********************************** */

static inline void ndpi_deserialize_single_int64(ndpi_private_deserializer *deserializer,
u_int32_t offset, int64_t *s) {
*s = ndpi_ntohll(*(int64_t*)&deserializer->buffer.data[offset]);
*s = ndpi_ntohll(get_u_int64_t(deserializer->buffer.data, offset));
}

/* ********************************** */
Expand Down
12 changes: 6 additions & 6 deletions src/lib/protocols/dns.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ static u_int16_t checkDNSSubprotocol(u_int16_t sport, u_int16_t dport) {
/* *********************************************** */

static u_int16_t get16(u_int *i, const u_int8_t *payload) {
u_int16_t v = *(u_int16_t*)&payload[*i];
u_int16_t v = get_u_int16_t(payload, *i);

(*i) += 2;

Expand Down Expand Up @@ -230,7 +230,7 @@ static u_int64_t fpc_dns_cache_key_from_packet(const unsigned char *ip, int ip_l
if(ip_len == 16)
key = ndpi_quick_hash64((const char *)ip, 16);
else
key = (u_int64_t)(*(u_int32_t *)ip);
key = (u_int64_t)get_u_int32_t(ip, 0);

return key;
}
Expand Down Expand Up @@ -581,21 +581,21 @@ static int process_additionals(struct ndpi_detection_module_struct *ndpi_struct,

if(rsp_type == 41 /* OPT */) {
/* https://en.wikipedia.org/wiki/Extension_Mechanisms_for_DNS */
flow->protos.dns.edns0_udp_payload_size = ntohs(*((u_int16_t*)&packet->payload[x])); /* EDNS(0) */
flow->protos.dns.edns0_udp_payload_size = ntohs(get_u_int16_t(packet->payload, x)); /* EDNS(0) */

#ifdef DNS_DEBUG
printf("[DNS] [response] edns0_udp_payload_size: %u\n", flow->protos.dns.edns0_udp_payload_size);
#endif
x += 6;

rdata_len = ntohs(*((u_int16_t *)&packet->payload[x]));
rdata_len = ntohs(get_u_int16_t(packet->payload, x));
#ifdef DNS_DEBUG
printf("[DNS] [response] rdata len: %u\n", rdata_len);
#endif
if(rdata_len > 0 &&
x + 6 <= packet->payload_packet_len) {
opt_code = ntohs(*((u_int16_t *)&packet->payload[x + 2]));
opt_len = ntohs(*((u_int16_t *)&packet->payload[x + 4]));
opt_code = ntohs(get_u_int16_t(packet->payload, x + 2));
opt_len = ntohs(get_u_int16_t(packet->payload, x + 4));
opt = &packet->payload[x + 6];
/* TODO: parse the TLV list */
if(opt_code == 0x03 &&
Expand Down
Loading