Coverage Report

Created: 2023-06-29 06:52

/src/ndpi/fuzz/fuzz_ndpi_reader.c
Line
Count
Source (jump to first uncovered line)
1
#include "reader_util.h"
2
#include "ndpi_api.h"
3
#include "fuzz_common_code.h"
4
5
#include <pcap/pcap.h>
6
7
#include <errno.h>
8
#include <stdint.h>
9
#include <stdio.h>
10
11
struct ndpi_workflow_prefs *prefs = NULL;
12
struct ndpi_workflow *workflow = NULL;
13
14
int nDPI_LogLevel = 0;
15
char *_debug_protocols = NULL;
16
u_int32_t current_ndpi_memory = 0, max_ndpi_memory = 0;
17
u_int8_t enable_protocol_guess = 1, enable_payload_analyzer = 0;
18
u_int8_t enable_flow_stats = 1;
19
u_int8_t human_readeable_string_len = 5;
20
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 */;
21
ndpi_init_prefs init_prefs = ndpi_track_flow_payload | ndpi_enable_ja3_plus | ndpi_enable_tcp_ack_payload_heuristic;
22
int enable_malloc_bins = 1;
23
int malloc_size_stats = 0;
24
int max_malloc_bins = 14;
25
struct ndpi_bin malloc_bins; /* unused */
26
27
extern void ndpi_report_payload_stats(FILE *out);
28
29
#ifdef CRYPT_FORCE_NO_AESNI
30
extern int force_no_aesni;
31
#endif
32
33
74.4k
FILE *bufferToFile(const uint8_t *Data, size_t Size) {
34
74.4k
  FILE *fd;
35
74.4k
  fd = tmpfile();
36
74.4k
  if (fd == NULL) {
37
0
    perror("Error tmpfile");
38
0
    return NULL;
39
0
  }
40
74.4k
  if (fwrite (Data, 1, Size, fd) != Size) {
41
0
    perror("Error fwrite");
42
0
    fclose(fd);
43
0
    return NULL;
44
0
  }
45
74.4k
  rewind(fd);
46
74.4k
  return fd;
47
74.4k
}
48
49
74.4k
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
50
74.4k
  pcap_t * pkts;
51
74.4k
  const u_char *pkt;
52
74.4k
  struct pcap_pkthdr *header;
53
74.4k
  int r;
54
74.4k
  char errbuf[PCAP_ERRBUF_SIZE];
55
74.4k
  NDPI_PROTOCOL_BITMASK all;
56
74.4k
  u_int i;
57
74.4k
  FILE *fd;
58
59
74.4k
  if (prefs == NULL) {
60
3
    prefs = calloc(sizeof(struct ndpi_workflow_prefs), 1);
61
3
    if (prefs == NULL) {
62
      //should not happen
63
0
      return 1;
64
0
    }
65
3
    prefs->decode_tunnels = 1;
66
3
    prefs->num_roots = 16;
67
3
    prefs->max_ndpi_flows = 16 * 1024 * 1024;
68
3
    prefs->quiet_mode = 0;
69
70
3
#ifdef ENABLE_MEM_ALLOC_FAILURES
71
3
    fuzz_set_alloc_callbacks();
72
3
#endif
73
74
3
    workflow = ndpi_workflow_init(prefs, NULL /* pcap handler will be set later */, 0, ndpi_serialization_format_json);
75
    // enable all protocols
76
3
    NDPI_BITMASK_SET_ALL(all);
77
3
    ndpi_set_protocol_detection_bitmask2(workflow->ndpi_struct, &all);
78
79
3
    ndpi_load_protocols_file(workflow->ndpi_struct, "protos.txt");
80
3
    ndpi_load_categories_file(workflow->ndpi_struct, "categories.txt", NULL);
81
3
    ndpi_load_risk_domain_file(workflow->ndpi_struct, "risky_domains.txt");
82
3
    ndpi_load_malicious_ja3_file(workflow->ndpi_struct, "ja3_fingerprints.csv");
83
3
    ndpi_load_malicious_sha1_file(workflow->ndpi_struct, "sha1_fingerprints.csv");
84
85
3
    memset(workflow->stats.protocol_counter, 0,
86
3
     sizeof(workflow->stats.protocol_counter));
87
3
    memset(workflow->stats.protocol_counter_bytes, 0,
88
3
     sizeof(workflow->stats.protocol_counter_bytes));
89
3
    memset(workflow->stats.protocol_flows, 0,
90
3
     sizeof(workflow->stats.protocol_flows));
91
3
    ndpi_finalize_initialization(workflow->ndpi_struct);
92
93
3
#ifdef CRYPT_FORCE_NO_AESNI
94
3
    force_no_aesni = 1;
95
3
#endif
96
97
#ifdef ENABLE_PAYLOAD_ANALYZER
98
   enable_payload_analyzer = 1;
99
#endif
100
3
  }
101
102
74.4k
#ifdef ENABLE_MEM_ALLOC_FAILURES
103
  /* Don't fail memory allocations until init phase is done */
104
74.4k
  fuzz_set_alloc_seed(Size);
105
74.4k
#endif
106
107
74.4k
  fd = bufferToFile(Data, Size);
108
74.4k
  if (fd == NULL)
109
0
    return 0;
110
111
74.4k
  pkts = pcap_fopen_offline(fd, errbuf);
112
74.4k
  if (pkts == NULL) {
113
6
    fclose(fd);
114
6
    return 0;
115
6
  }
116
74.4k
  if (ndpi_is_datalink_supported(pcap_datalink(pkts)) == 0)
117
132
  {
118
    /* Do not fail if the datalink type is not supported (may happen often during fuzzing). */
119
132
    pcap_close(pkts);
120
132
    return 0;
121
132
  }
122
123
74.3k
  workflow->pcap_handle = pkts;
124
  /* Init flow tree */
125
74.3k
  workflow->ndpi_flows_root = ndpi_calloc(workflow->prefs.num_roots, sizeof(void *));
126
74.3k
  if(!workflow->ndpi_flows_root) {
127
0
    pcap_close(pkts);
128
0
    return 0;
129
0
  }
130
131
74.3k
  header = NULL;
132
74.3k
  r = pcap_next_ex(pkts, &header, &pkt);
133
2.23M
  while (r > 0) {
134
    /* allocate an exact size buffer to check overflows */
135
2.15M
    uint8_t *packet_checked = malloc(header->caplen);
136
137
2.15M
    if(packet_checked) {
138
2.15M
      ndpi_risk flow_risk;
139
140
2.15M
      memcpy(packet_checked, pkt, header->caplen);
141
2.15M
      ndpi_workflow_process_packet(workflow, header, packet_checked, &flow_risk);
142
2.15M
      free(packet_checked);
143
2.15M
    }
144
145
2.15M
    r = pcap_next_ex(pkts, &header, &pkt);
146
2.15M
  }
147
74.3k
  pcap_close(pkts);
148
149
  /* Free flow trees */
150
1.26M
  for(i = 0; i < workflow->prefs.num_roots; i++)
151
1.18M
    ndpi_tdestroy(workflow->ndpi_flows_root[i], ndpi_flow_info_freer);
152
74.3k
  ndpi_free(workflow->ndpi_flows_root);
153
  /* Free payload analyzer data, without printing */
154
74.3k
  if(enable_payload_analyzer)
155
20.0k
    ndpi_report_payload_stats(NULL);
156
157
74.3k
  return 0;
158
74.3k
}