suricata
fuzz_sigpcap.c
Go to the documentation of this file.
1 /**
2  * @file
3  * @author Philippe Antoine <contact@catenacyber.fr>
4  * fuzz target for signature file and pcap file
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-proto-name.h"
16 #include "detect-engine-tag.h"
18 #include "host-bit.h"
19 #include "ippair-bit.h"
20 #include "app-layer-htp.h"
21 #include "detect-fast-pattern.h"
22 #include "util-unittest-helper.h"
23 #include "conf-yaml-loader.h"
24 #include "pkt-var.h"
25 #include "flow-util.h"
26 
27 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
28 
29 
30 static int initialized = 0;
33 //FlowWorkerThreadData
34 void *fwd;
36 
37 #include "confyaml.c"
38 
39 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
40 {
41  pcap_t * pkts;
42  char errbuf[PCAP_ERRBUF_SIZE];
43  const u_char *pkt;
44  struct pcap_pkthdr *header;
45  int r;
46  Packet *p;
47  size_t pos;
48  size_t pcap_cnt = 0;
49 
50  if (initialized == 0) {
51  //Redirects logs to /dev/null
52  setenv("SC_LOG_OP_IFACE", "file", 0);
53  setenv("SC_LOG_FILE", "/dev/null", 0);
54 
55  InitGlobal();
56 
59  //redirect logs to /tmp
60  ConfigSetLogDirectory("/tmp/");
61  //disables checksums validation for fuzzing
63  abort();
64  }
65  // do not load rules before reproducible DetectEngineReload
66  remove("/tmp/fuzz.rules");
67  surifuzz.sig_file = strdup("/tmp/fuzz.rules");
69  //loads rules after init
71 
75 
76  memset(&tv, 0, sizeof(tv));
78  if (tv.flow_queue == NULL)
79  abort();
84 
85  extern intmax_t max_pending_packets;
86  max_pending_packets = 128;
88  initialized = 1;
89  }
90 
91  /* TODO add yaml config
92  for (pos = 0; pos < size; pos++) {
93  if (data[pos] == 0) {
94  break;
95  }
96  }
97  if (ConfYamlLoadString(data, pos) != 0) {
98  return 0;
99  }
100  if (pos < size) {
101  //skip zero
102  pos++;
103  }
104  data += pos;
105  size -= pos;*/
106 
107  for (pos=0; pos < size; pos++) {
108  if (data[pos] == 0) {
109  break;
110  }
111  }
112  if (pos > 0 && pos < size) {
113  // dump signatures to a file so as to reuse SigLoadSignatures
114  if (TestHelperBufferToFile(surifuzz.sig_file, data, pos-1) < 0) {
115  return 0;
116  }
117  } else {
118  if (TestHelperBufferToFile(surifuzz.sig_file, data, pos) < 0) {
119  return 0;
120  }
121  }
122 
123  if (DetectEngineReload(&surifuzz) < 0) {
124  return 0;
125  }
127 
129  de_ctx->ref_cnt--;
131  FlowWorkerReplaceDetectCtx(fwd, new_det_ctx);
132 
133  DetectEngineThreadCtxDeinit(NULL, old_det_ctx);
134 
135  if (pos < size) {
136  //skip zero
137  pos++;
138  }
139  data += pos;
140  size -= pos;
141 
142  //rewrite buffer to a file as libpcap does not have buffer inputs
143  if (TestHelperBufferToFile("/tmp/fuzz.pcap", data, size) < 0) {
144  return 0;
145  }
146 
147  //initialize structure
148  pkts = pcap_open_offline("/tmp/fuzz.pcap", errbuf);
149  if (pkts == NULL) {
150  return 0;
151  }
152 
153  //loop over packets
154  r = pcap_next_ex(pkts, &header, &pkt);
155  p = PacketGetFromAlloc();
156  p->ts.tv_sec = header->ts.tv_sec;
157  p->ts.tv_usec = header->ts.tv_usec % 1000000;
158  p->datalink = pcap_datalink(pkts);
159  while (r > 0) {
160  if (PacketCopyData(p, pkt, header->caplen) == 0) {
161  // DecodePcapFile
163  if (ecode == TM_ECODE_FAILED) {
164  break;
165  }
166  Packet *extra_p = PacketDequeueNoLock(&tv.decode_pq);
167  while (extra_p != NULL) {
168  PacketFreeOrRelease(extra_p);
169  extra_p = PacketDequeueNoLock(&tv.decode_pq);
170  }
172  extra_p = PacketDequeueNoLock(&tv.decode_pq);
173  while (extra_p != NULL) {
174  PacketFreeOrRelease(extra_p);
175  extra_p = PacketDequeueNoLock(&tv.decode_pq);
176  }
177  }
178  r = pcap_next_ex(pkts, &header, &pkt);
179  PACKET_RECYCLE(p);
180  p->ts.tv_sec = header->ts.tv_sec;
181  p->ts.tv_usec = header->ts.tv_usec % 1000000;
182  p->datalink = pcap_datalink(pkts);
183  pcap_cnt++;
184  p->pcap_cnt = pcap_cnt;
185  }
186  //close structure
187  pcap_close(pkts);
188  PacketFree(p);
189  FlowReset();
190 
191  return 0;
192 }
ThreadVars_::flow_queue
struct FlowQueue_ * flow_queue
Definition: threadvars.h:133
detect-engine.h
DetectEngineThreadCtxInitForReload
DetectEngineThreadCtx * DetectEngineThreadCtxInitForReload(ThreadVars *tv, DetectEngineCtx *new_de_ctx, int mt)
Definition: detect-engine.c:3207
PacketFreeOrRelease
void PacketFreeOrRelease(Packet *p)
Return a packet to where it was allocated.
Definition: decode.c:194
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:295
source-pcap-file.h
tv
ThreadVars tv
Definition: fuzz_sigpcap.c:31
fwd
void * fwd
Definition: fuzz_sigpcap.c:34
DetectEngineCtx_::ref_cnt
uint32_t ref_cnt
Definition: detect.h:948
Packet_::pcap_cnt
uint64_t pcap_cnt
Definition: decode.h:588
ippair-bit.h
LLVMFuzzerTestOneInput
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
Definition: fuzz_sigpcap.c:39
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:811
DetectEngineGetCurrent
DetectEngineCtx * DetectEngineGetCurrent(void)
Definition: detect-engine.c:3597
FlowReset
void FlowReset(void)
Definition: flow.c:649
StatsSetupPrivate
int StatsSetupPrivate(ThreadVars *tv)
Definition: counters.c:1191
GlobalsInitPreConfig
void GlobalsInitPreConfig(void)
Definition: suricata.c:373
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:83
util-unittest-helper.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_sigpcap.c:32
PacketPoolInit
void PacketPoolInit(void)
Definition: tmqh-packetpool.c:302
Packet_::datalink
int datalink
Definition: decode.h:601
DecodeRegisterPerfCounters
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:517
util-cidr.h
app-layer-htp.h
PreRunPostPrivsDropInit
void PreRunPostPrivsDropInit(const int runmode)
Definition: suricata.c:2158
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1060
PacketDequeueNoLock
Packet * PacketDequeueNoLock(PacketQueueNoLock *qnl)
Definition: packet-queue.c:206
util-reference-config.h
SCInstance_::delayed_detect
int delayed_detect
Definition: suricata.h:148
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
pkt-var.h
TmModule_::Func
TmEcode(* Func)(ThreadVars *, Packet *, void *)
Definition: tm-modules.h:52
PacketFree
void PacketFree(Packet *p)
Return a malloced packet.
Definition: decode.c:134
TestHelperBufferToFile
int TestHelperBufferToFile(const char *name, const uint8_t *data, size_t size)
writes the contents of a buffer into a file
Definition: util-unittest-helper.c:101
ConfYamlLoadString
int ConfYamlLoadString(const char *string, size_t len)
Load configuration from a YAML string.
Definition: conf-yaml-loader.c:487
PostConfLoadedSetup
int PostConfLoadedSetup(SCInstance *suri)
Definition: suricata.c:2571
detect-engine-tag.h
Packet_
Definition: decode.h:427
PostConfLoadedDetectSetup
void PostConfLoadedDetectSetup(SCInstance *suri)
Definition: suricata.c:2452
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:81
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
FlowWorkerGetDetectCtxPtr
void * FlowWorkerGetDetectCtxPtr(void *flow_worker)
Definition: flow-worker.c:607
detect-fast-pattern.h
Packet_::ts
struct timeval ts
Definition: decode.h:470
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3354
configNoChecksum
const char configNoChecksum[]
Definition: confyaml.c:1
run_mode
int run_mode
Definition: suricata.c:203
TmModule_::ThreadInit
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:47
util-classification-config.h
SCInstance_::sig_file
char * sig_file
Definition: suricata.h:128
ConfigSetLogDirectory
TmEcode ConfigSetLogDirectory(const char *name)
Definition: util-conf.c:30
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:173
SCInstance_::sig_file_exclusive
int sig_file_exclusive
Definition: suricata.h:129
max_pending_packets
int max_pending_packets
Definition: suricata.c:214
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:654
DecodeThreadVarsAlloc
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:675
ThreadVars_::decode_pq
PacketQueueNoLock decode_pq
Definition: threadvars.h:110
FlowQueueNew
FlowQueue * FlowQueueNew()
Definition: flow-queue.c:36
DetectEngineReload
int DetectEngineReload(const SCInstance *suri)
Reload the detection engine.
Definition: detect-engine.c:4428
SCInstance_
Definition: suricata.h:123
InitGlobal
int InitGlobal(void)
Global initialization common to all runmodes.
Definition: suricata.c:2790
surifuzz
SCInstance surifuzz
Definition: fuzz_sigpcap.c:35
RUNMODE_PCAP_FILE
@ RUNMODE_PCAP_FILE
Definition: runmodes.h:30
PACKET_RECYCLE
#define PACKET_RECYCLE(p)
Definition: decode.h:862
host-bit.h
detect-engine-threshold.h
FlowWorkerReplaceDetectCtx
void FlowWorkerReplaceDetectCtx(void *flow_worker, void *detect_ctx)
Definition: flow-worker.c:600
app-layer.h