suricata
fuzz_predefpcap_aware.c
Go to the documentation of this file.
1 /**
2  * @file
3  * @author Philippe Antoine <contact@catenacyber.fr>
4  * fuzz target for predefined signatures and pcap (aware)
5  */
6 
7 #include "suricata-common.h"
8 #include "source-pcap-file.h"
9 #include "detect-engine.h"
11 #include "util-reference-config.h"
12 #include "app-layer.h"
13 #include "tm-queuehandlers.h"
14 #include "util-cidr.h"
15 #include "util-profiling.h"
16 #include "util-proto-name.h"
17 #include "detect-engine-tag.h"
19 #include "host-bit.h"
20 #include "ippair-bit.h"
21 #include "app-layer-htp.h"
22 #include "detect-fast-pattern.h"
23 #include "util-unittest-helper.h"
24 #include "conf-yaml-loader.h"
25 #include "pkt-var.h"
26 #include "flow-util.h"
27 #include "tm-modules.h"
28 #include "tmqh-packetpool.h"
29 #include "util-conf.h"
30 #include "packet.h"
31 
32 #include <fuzz_pcap.h>
33 
34 int LLVMFuzzerInitialize(const int *argc, char ***argv);
35 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
36 
37 static int initialized = 0;
40 // FlowWorkerThreadData
41 void *fwd;
43 SC_ATOMIC_EXTERN(unsigned int, engine_stage);
44 
45 #include "confyaml.c"
46 
47 char *filepath = NULL;
48 
49 int LLVMFuzzerInitialize(const int *argc, char ***argv)
50 {
51  filepath = dirname(strdup((*argv)[0]));
52  return 0;
53 }
54 
55 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
56 {
57  FPC_buffer_t pkts;
58  const u_char *pkt;
59  struct pcap_pkthdr header;
60  int r;
61  Packet *p;
62  size_t pcap_cnt = 0;
63 
64  if (initialized == 0) {
65  // Redirects logs to /dev/null
66  setenv("SC_LOG_OP_IFACE", "file", 0);
67  setenv("SC_LOG_FILE", "/dev/null", 0);
68 
69  InitGlobal();
70 
73  // redirect logs to /tmp
74  ConfigSetLogDirectory("/tmp/");
75  // disables checksums validation for fuzzing
77  abort();
78  }
79  surifuzz.sig_file = malloc(strlen(filepath) + strlen("/fuzz.rules") + 1);
80  memcpy(surifuzz.sig_file, filepath, strlen(filepath));
81  memcpy(surifuzz.sig_file + strlen(filepath), "/fuzz.rules", strlen("/fuzz.rules"));
82  surifuzz.sig_file[strlen(filepath) + strlen("/fuzz.rules")] = 0;
84  // loads rules after init
86 
90 
91  memset(&tv, 0, sizeof(tv));
93  if (tv.flow_queue == NULL)
94  abort();
99 
100  extern uint16_t max_pending_packets;
101  max_pending_packets = 128;
102  PacketPoolInit();
103  if (DetectEngineReload(&surifuzz) < 0) {
104  return 0;
105  }
106 
107  SC_ATOMIC_SET(engine_stage, SURICATA_RUNTIME);
108  initialized = 1;
109  }
110 
111  if (size < FPC0_HEADER_LEN) {
112  return 0;
113  }
114  // initialize FPC with the buffer
115  if (FPC_init(&pkts, data, size) < 0) {
116  return 0;
117  }
118 
119  // loop over packets
120  r = FPC_next(&pkts, &header, &pkt);
121  p = PacketGetFromAlloc();
122  if (p == NULL || r <= 0 || header.ts.tv_sec >= INT_MAX - 3600) {
123  goto bail;
124  }
125  p->ts = SCTIME_FROM_TIMEVAL(&header.ts);
126  p->datalink = pkts.datalink;
127  p->pkt_src = PKT_SRC_WIRE;
128  while (r > 0) {
129  if (PacketCopyData(p, pkt, header.caplen) == 0) {
130  // DecodePcapFile
132  if (ecode == TM_ECODE_FAILED) {
133  break;
134  }
135  Packet *extra_p = PacketDequeueNoLock(&tv.decode_pq);
136  while (extra_p != NULL) {
137  PacketFreeOrRelease(extra_p);
138  extra_p = PacketDequeueNoLock(&tv.decode_pq);
139  }
141  extra_p = PacketDequeueNoLock(&tv.decode_pq);
142  while (extra_p != NULL) {
143  PacketFreeOrRelease(extra_p);
144  extra_p = PacketDequeueNoLock(&tv.decode_pq);
145  }
146  }
147  r = FPC_next(&pkts, &header, &pkt);
148  if (r <= 0 || header.ts.tv_sec >= INT_MAX - 3600) {
149  goto bail;
150  }
151  PacketRecycle(p);
152  p->ts = SCTIME_FROM_TIMEVAL(&header.ts);
153  p->datalink = pkts.datalink;
154  pcap_cnt++;
155  p->pcap_cnt = pcap_cnt;
156  p->pkt_src = PKT_SRC_WIRE;
157  }
158 bail:
159  if (p != NULL) {
160  PacketFree(p);
161  }
162  FlowReset();
163 
164  return 0;
165 }
ThreadVars_::flow_queue
struct FlowQueue_ * flow_queue
Definition: threadvars.h:134
LLVMFuzzerTestOneInput
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
Definition: fuzz_predefpcap_aware.c:55
detect-engine.h
PacketFreeOrRelease
void PacketFreeOrRelease(Packet *p)
Return a packet to where it was allocated.
Definition: decode.c:191
flow-util.h
PacketCopyData
int PacketCopyData(Packet *p, const uint8_t *pktdata, uint32_t pktlen)
Copy data to Packet payload and set packet length.
Definition: decode.c:292
source-pcap-file.h
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:386
filepath
char * filepath
Definition: fuzz_predefpcap_aware.c:47
Packet_::pcap_cnt
uint64_t pcap_cnt
Definition: decode.h:607
ippair-bit.h
PacketRecycle
void PacketRecycle(Packet *p)
Definition: packet.c:170
FlowReset
void FlowReset(void)
Definition: flow.c:679
StatsSetupPrivate
int StatsSetupPrivate(ThreadVars *tv)
Definition: counters.c:1224
tm-modules.h
GlobalsInitPreConfig
void GlobalsInitPreConfig(void)
Definition: suricata.c:357
SURICATA_RUNTIME
@ SURICATA_RUNTIME
Definition: suricata.h:96
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:85
tmqh-packetpool.h
util-unittest-helper.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_predefpcap_aware.c:39
PacketPoolInit
void PacketPoolInit(void)
Definition: tmqh-packetpool.c:262
Packet_::datalink
int datalink
Definition: decode.h:620
DecodeRegisterPerfCounters
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:528
util-cidr.h
app-layer-htp.h
PreRunPostPrivsDropInit
void PreRunPostPrivsDropInit(const int runmode)
Definition: suricata.c:2248
PKT_SRC_WIRE
@ PKT_SRC_WIRE
Definition: decode.h:54
Packet_::ts
SCTime_t ts
Definition: decode.h:484
PacketDequeueNoLock
Packet * PacketDequeueNoLock(PacketQueueNoLock *qnl)
Definition: packet-queue.c:208
util-reference-config.h
SCInstance_::delayed_detect
int delayed_detect
Definition: suricata.h:149
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
SCTIME_FROM_TIMEVAL
#define SCTIME_FROM_TIMEVAL(tv)
Definition: util-time.h:79
pkt-var.h
TmModule_::Func
TmEcode(* Func)(ThreadVars *, Packet *, void *)
Definition: tm-modules.h:53
PacketFree
void PacketFree(Packet *p)
Return a malloced packet.
Definition: decode.c:134
FlowQueueNew
FlowQueue * FlowQueueNew(void)
Definition: flow-queue.c:35
ConfYamlLoadString
int ConfYamlLoadString(const char *string, size_t len)
Load configuration from a YAML string.
Definition: conf-yaml-loader.c:511
PostConfLoadedSetup
int PostConfLoadedSetup(SCInstance *suri)
Definition: suricata.c:2633
detect-engine-tag.h
util-profiling.h
Packet_
Definition: decode.h:436
PostConfLoadedDetectSetup
void PostConfLoadedDetectSetup(SCInstance *suri)
Definition: suricata.c:2542
tmm_modules
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.c:33
conf-yaml-loader.h
TMM_DECODEPCAPFILE
@ TMM_DECODEPCAPFILE
Definition: tm-threads-common.h:41
confyaml.c
TmEcode
TmEcode
Definition: tm-threads-common.h:83
max_pending_packets
uint16_t max_pending_packets
Definition: suricata.c:187
util-proto-name.h
setenv
void setenv(const char *name, const char *value, int overwrite)
TMM_FLOWWORKER
@ TMM_FLOWWORKER
Definition: tm-threads-common.h:34
tm-queuehandlers.h
detect-fast-pattern.h
util-conf.h
fwd
void * fwd
Definition: fuzz_predefpcap_aware.c:41
suricata-common.h
configNoChecksum
const char configNoChecksum[]
Definition: confyaml.c:1
run_mode
int run_mode
Definition: suricata.c:176
tv
ThreadVars tv
Definition: fuzz_predefpcap_aware.c:38
SC_ATOMIC_EXTERN
SC_ATOMIC_EXTERN(unsigned int, engine_stage)
packet.h
TmModule_::ThreadInit
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:48
LLVMFuzzerInitialize
int LLVMFuzzerInitialize(const int *argc, char ***argv)
Definition: fuzz_predefpcap_aware.c:49
util-classification-config.h
SCInstance_::sig_file
char * sig_file
Definition: suricata.h:128
ConfigSetLogDirectory
TmEcode ConfigSetLogDirectory(const char *name)
Definition: util-conf.c:33
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:173
Packet_::pkt_src
uint8_t pkt_src
Definition: decode.h:592
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:685
DecodeThreadVarsAlloc
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:691
ThreadVars_::decode_pq
PacketQueueNoLock decode_pq
Definition: threadvars.h:111
DetectEngineReload
int DetectEngineReload(const SCInstance *suri)
Reload the detection engine.
Definition: detect-engine.c:4682
SCInstance_
Definition: suricata.h:123
InitGlobal
int InitGlobal(void)
Global initialization common to all runmodes.
Definition: suricata.c:2858
SCInstance_::sig_file_exclusive
bool sig_file_exclusive
Definition: suricata.h:129
RUNMODE_PCAP_FILE
@ RUNMODE_PCAP_FILE
Definition: runmodes.h:30
surifuzz
SCInstance surifuzz
Definition: fuzz_predefpcap_aware.c:42
host-bit.h
detect-engine-threshold.h
app-layer.h