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-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 "flow-worker.h"
28 #include "tm-modules.h"
29 #include "tmqh-packetpool.h"
30 #include "util-file.h"
31 #include "util-conf.h"
32 #include "packet.h"
33 #include "nallocinc.c"
34 
35 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
36 
37 
38 static int initialized = 0;
41 //FlowWorkerThreadData
42 void *fwd;
44 SC_ATOMIC_EXTERN(unsigned int, engine_stage);
45 
46 extern const char *configNoChecksum;
47 
48 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
49 {
50  pcap_t * pkts;
51  char errbuf[PCAP_ERRBUF_SIZE];
52  const u_char *pkt;
53  struct pcap_pkthdr *header;
54  int r;
55  Packet *p;
56  size_t pos;
57  size_t pcap_cnt = 0;
58 
59  if (initialized == 0) {
60  //Redirects logs to /dev/null
61  setenv("SC_LOG_OP_IFACE", "file", 0);
62  setenv("SC_LOG_FILE", "/dev/null", 0);
63 
64  InitGlobal();
65 
68  //redirect logs to /tmp
69  ConfigSetLogDirectory("/tmp/");
70  //disables checksums validation for fuzzing
72  abort();
73  }
74  // do not load rules before reproducible DetectEngineReload
75  remove("/tmp/fuzz.rules");
76  surifuzz.sig_file = strdup("/tmp/fuzz.rules");
78  //loads rules after init
80 
84 
85  memset(&tv, 0, sizeof(tv));
87  if (tv.flow_queue == NULL)
88  abort();
92  StatsSetupPrivate(&tv.stats, NULL);
93 
94  extern uint32_t max_pending_packets;
95  max_pending_packets = 128;
97  SC_ATOMIC_SET(engine_stage, SURICATA_RUNTIME);
98  nalloc_init(NULL);
100  initialized = 1;
101  }
102 
103  /* TODO add yaml config
104  for (pos = 0; pos < size; pos++) {
105  if (data[pos] == 0) {
106  break;
107  }
108  }
109  if (SCConfYamlLoadString(data, pos) != 0) {
110  return 0;
111  }
112  if (pos < size) {
113  //skip zero
114  pos++;
115  }
116  data += pos;
117  size -= pos;*/
118 
119  for (pos=0; pos < size; pos++) {
120  if (data[pos] == 0) {
121  break;
122  }
123  }
124  if (pos > 0 && pos < size) {
125  // dump signatures to a file so as to reuse SigLoadSignatures
126  if (TestHelperBufferToFile(surifuzz.sig_file, data, pos-1) < 0) {
127  return 0;
128  }
129  } else {
130  if (TestHelperBufferToFile(surifuzz.sig_file, data, pos) < 0) {
131  return 0;
132  }
133  }
134 
135  if (DetectEngineReload(&surifuzz) < 0) {
136  return 0;
137  }
139 
141  de_ctx->ref_cnt--;
143  FlowWorkerReplaceDetectCtx(fwd, new_det_ctx);
144 
145  DetectEngineThreadCtxDeinit(NULL, old_det_ctx);
146 
147  if (pos < size) {
148  //skip zero
149  pos++;
150  }
151  data += pos;
152  size -= pos;
153 
154  //rewrite buffer to a file as libpcap does not have buffer inputs
155  if (TestHelperBufferToFile("/tmp/fuzz.pcap", data, size) < 0) {
156  return 0;
157  }
158 
159  //initialize structure
160  pkts = pcap_open_offline("/tmp/fuzz.pcap", errbuf);
161  if (pkts == NULL) {
162  return 0;
163  }
164 
165  nalloc_start(data, size);
166  //loop over packets
167  r = pcap_next_ex(pkts, &header, &pkt);
168  p = PacketGetFromAlloc();
169  if (p == NULL || r <= 0 || header->ts.tv_sec >= INT_MAX - 3600 || header->ts.tv_usec < 0) {
170  goto bail;
171  }
172  p->ts = SCTIME_FROM_TIMEVAL(&header->ts);
173  p->datalink = pcap_datalink(pkts);
174  p->pkt_src = PKT_SRC_WIRE;
175  while (r > 0) {
176  if (PacketCopyData(p, pkt, header->caplen) == 0) {
177  // DecodePcapFile
179  if (ecode == TM_ECODE_FAILED) {
180  break;
181  }
182  Packet *extra_p = PacketDequeueNoLock(&tv.decode_pq);
183  while (extra_p != NULL) {
184  PacketFreeOrRelease(extra_p);
185  extra_p = PacketDequeueNoLock(&tv.decode_pq);
186  }
188  extra_p = PacketDequeueNoLock(&tv.decode_pq);
189  while (extra_p != NULL) {
190  PacketFreeOrRelease(extra_p);
191  extra_p = PacketDequeueNoLock(&tv.decode_pq);
192  }
193  }
194  r = pcap_next_ex(pkts, &header, &pkt);
195  if (r <= 0 || header->ts.tv_sec >= INT_MAX - 3600 || header->ts.tv_usec < 0) {
196  goto bail;
197  }
198  PacketRecycle(p);
199  p->ts = SCTIME_FROM_TIMEVAL(&header->ts);
200  p->datalink = pcap_datalink(pkts);
201  p->pkt_src = PKT_SRC_WIRE;
202  pcap_cnt++;
203  p->pcap_cnt = pcap_cnt;
204  }
205 bail:
206  //close structure
207  pcap_close(pkts);
208  PacketFree(p);
209  FlowReset();
210  nalloc_end();
211 
212  return 0;
213 }
SCConfYamlLoadString
int SCConfYamlLoadString(const char *string, size_t len)
Load configuration from a YAML string.
Definition: conf-yaml-loader.c:535
ThreadVars_::flow_queue
struct FlowQueue_ * flow_queue
Definition: threadvars.h:131
ts
uint64_t ts
Definition: source-erf-file.c:55
detect-engine.h
DetectEngineThreadCtxInitForReload
DetectEngineThreadCtx * DetectEngineThreadCtxInitForReload(ThreadVars *tv, DetectEngineCtx *new_de_ctx, int mt)
Definition: detect-engine.c:3452
PacketFreeOrRelease
void PacketFreeOrRelease(Packet *p)
Return a packet to where it was allocated.
Definition: decode.c:280
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:381
source-pcap-file.h
tv
ThreadVars tv
Definition: fuzz_sigpcap.c:39
fwd
void * fwd
Definition: fuzz_sigpcap.c:42
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:386
DetectEngineCtx_::ref_cnt
uint32_t ref_cnt
Definition: detect.h:1057
Packet_::pcap_cnt
uint64_t pcap_cnt
Definition: decode.h:626
ippair-bit.h
PacketRecycle
void PacketRecycle(Packet *p)
Definition: packet.c:160
LLVMFuzzerTestOneInput
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
Definition: fuzz_sigpcap.c:48
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:933
DetectEngineGetCurrent
DetectEngineCtx * DetectEngineGetCurrent(void)
Definition: detect-engine.c:3838
FlowReset
void FlowReset(void)
Definition: flow.c:675
SC_ATOMIC_EXTERN
SC_ATOMIC_EXTERN(unsigned int, engine_stage)
tm-modules.h
GlobalsInitPreConfig
void GlobalsInitPreConfig(void)
Definition: suricata.c:386
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:82
tmqh-packetpool.h
nallocinc.c
util-unittest-helper.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_sigpcap.c:40
PacketPoolInit
void PacketPoolInit(void)
Definition: tmqh-packetpool.c:235
SCRunmodeSet
void SCRunmodeSet(SCRunMode run_mode)
Set the current run mode.
Definition: suricata.c:288
Packet_::datalink
int datalink
Definition: decode.h:639
DecodeRegisterPerfCounters
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:632
util-cidr.h
app-layer-htp.h
SCRunmodeGet
SCRunMode SCRunmodeGet(void)
Get the current run mode.
Definition: suricata.c:283
PreRunPostPrivsDropInit
void PreRunPostPrivsDropInit(const int runmode)
Definition: suricata.c:2330
PKT_SRC_WIRE
@ PKT_SRC_WIRE
Definition: decode.h:52
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:19
SURICATA_RUNTIME
@ SURICATA_RUNTIME
Definition: suricata.h:101
DetectEngineThreadCtx_
Definition: detect.h:1245
Packet_::ts
SCTime_t ts
Definition: decode.h:555
PacketDequeueNoLock
Packet * PacketDequeueNoLock(PacketQueueNoLock *qnl)
Definition: packet-queue.c:208
flow-worker.h
util-reference-config.h
SCInstance_::delayed_detect
int delayed_detect
Definition: suricata.h:165
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
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:56
PacketFree
void PacketFree(Packet *p)
Return a malloced packet.
Definition: decode.c:223
FlowQueueNew
FlowQueue * FlowQueueNew(void)
Definition: flow-queue.c:35
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:103
PostConfLoadedSetup
int PostConfLoadedSetup(SCInstance *suri)
Definition: suricata.c:2737
detect-engine-tag.h
util-profiling.h
Packet_
Definition: decode.h:501
PostConfLoadedDetectSetup
void PostConfLoadedDetectSetup(SCInstance *suri)
Definition: suricata.c:2646
tmm_modules
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.c:29
conf-yaml-loader.h
TMM_DECODEPCAPFILE
@ TMM_DECODEPCAPFILE
Definition: tm-threads-common.h:41
TmEcode
TmEcode
Definition: tm-threads-common.h:80
util-proto-name.h
setenv
void setenv(const char *name, const char *value, int overwrite)
StatsSetupPrivate
int StatsSetupPrivate(StatsThreadContext *stats, const char *thread_name)
Definition: counters.c:1229
max_pending_packets
uint32_t max_pending_packets
Definition: suricata.c:187
TMM_FLOWWORKER
@ TMM_FLOWWORKER
Definition: tm-threads-common.h:34
tm-queuehandlers.h
nalloc_init
#define nalloc_init(x)
Definition: nallocinc.c:49
util-file.h
FlowWorkerGetDetectCtxPtr
void * FlowWorkerGetDetectCtxPtr(void *flow_worker)
Definition: flow-worker.c:749
detect-fast-pattern.h
util-conf.h
suricata-common.h
nalloc_start
#define nalloc_start(x, y)
Definition: nallocinc.c:51
packet.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
Definition: detect-engine.c:3601
TmModule_::ThreadInit
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:51
util-classification-config.h
nalloc_end
#define nalloc_end()
Definition: nallocinc.c:52
SCInstance_::sig_file
char * sig_file
Definition: suricata.h:138
ConfigSetLogDirectory
TmEcode ConfigSetLogDirectory(const char *name)
Definition: util-conf.c:33
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:262
Packet_::pkt_src
uint8_t pkt_src
Definition: decode.h:611
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:963
DecodeThreadVarsAlloc
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:816
ThreadVars_::decode_pq
PacketQueueNoLock decode_pq
Definition: threadvars.h:111
nalloc_restrict_file_prefix
#define nalloc_restrict_file_prefix(x)
Definition: nallocinc.c:50
DetectEngineReload
int DetectEngineReload(const SCInstance *suri)
Reload the detection engine.
Definition: detect-engine.c:4791
SCInstance_
Definition: suricata.h:133
InitGlobal
int InitGlobal(void)
Global initialization common to all runmodes.
Definition: suricata.c:2986
surifuzz
SCInstance surifuzz
Definition: fuzz_sigpcap.c:43
SCInstance_::sig_file_exclusive
bool sig_file_exclusive
Definition: suricata.h:139
RUNMODE_PCAP_FILE
@ RUNMODE_PCAP_FILE
Definition: runmodes.h:30
ThreadVars_::stats
StatsThreadContext stats
Definition: threadvars.h:121
configNoChecksum
const char * configNoChecksum
Definition: confyaml.c:1
host-bit.h
detect-engine-threshold.h
FlowWorkerReplaceDetectCtx
void FlowWorkerReplaceDetectCtx(void *flow_worker, void *detect_ctx)
Definition: flow-worker.c:742
app-layer.h