suricata
fuzz_sigpcap_aware.c
Go to the documentation of this file.
1/**
2 * @file
3 * @author Philippe Antoine <contact@catenacyber.fr>
4 * fuzz target for AppLayerProtoDetectGetProto
5 */
6
7#include "suricata-common.h"
8#include "source-pcap-file.h"
9#include "detect-engine.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"
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-conf.h"
31#include "packet.h"
32
33#include <fuzz_pcap.h>
34
35int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
36
37static int initialized = 0;
40// FlowWorkerThreadData
41void *fwd;
43SC_ATOMIC_EXTERN(unsigned int, engine_stage);
44
45extern const char *configNoChecksum;
46
47static void SigGenerateAware(const uint8_t *data, size_t size, char *r, size_t *len)
48{
49 *len = snprintf(r, 511, "alert ip any any -> any any (");
50 for (size_t i = 0; i + 1 < size && *len < 511; i++) {
51 if (data[i] & 0x80) {
52 size_t off = (data[i] & 0x7F + ((data[i + 1] & 0xF) << 7)) % (DETECT_TBLSIZE);
54 ((data[i + 1] & 0x80) && sigmatch_table[off].flags & SIGMATCH_OPTIONAL_OPT)) {
55 *len += snprintf(r + *len, 511 - *len, "; %s;", sigmatch_table[off].name);
56 } else {
57 *len += snprintf(r + *len, 511 - *len, "; %s:", sigmatch_table[off].name);
58 }
59 i++;
60 } else {
61 r[*len] = data[i];
62 *len = *len + 1;
63 }
64 }
65 if (*len < 511) {
66 *len += snprintf(r + *len, 511 - *len, ")");
67 } else {
68 r[511] = 0;
69 *len = 511;
70 }
71}
72
73int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
74{
75 FPC_buffer_t pkts;
76 const u_char *pkt;
77 struct pcap_pkthdr header;
78 int r;
79 Packet *p;
80 size_t pos;
81 size_t pcap_cnt = 0;
82
83 if (initialized == 0) {
84 // Redirects logs to /dev/null
85 setenv("SC_LOG_OP_IFACE", "file", 0);
86 setenv("SC_LOG_FILE", "/dev/null", 0);
87
88 InitGlobal();
89
92 // redirect logs to /tmp
93 ConfigSetLogDirectory("/tmp/");
94 // disables checksums validation for fuzzing
96 abort();
97 }
98 // do not load rules before reproducible DetectEngineReload
99 remove("/tmp/fuzz.rules");
100 surifuzz.sig_file = strdup("/tmp/fuzz.rules");
102 // loads rules after init
104
108
109 memset(&tv, 0, sizeof(tv));
111 if (tv.flow_queue == NULL)
112 abort();
117
118 extern uint32_t max_pending_packets;
121 SC_ATOMIC_SET(engine_stage, SURICATA_RUNTIME);
122 initialized = 1;
123 }
124
125 if (size < 1 + FPC0_HEADER_LEN) {
126 return 0;
127 }
128 for (pos = 0; pos < size - FPC0_HEADER_LEN; pos++) {
129 if (data[pos] == 0) {
130 break;
131 }
132 }
133 // initialize FPC with the buffer
134 if (FPC_init(&pkts, data + pos + 1, size - pos - 1) < 0) {
135 return 0;
136 }
137
138 // dump signatures to a file so as to reuse SigLoadSignatures
139 char sigaware[512];
140 size_t len;
141 SigGenerateAware(data, pos + 1, sigaware, &len);
142 if (TestHelperBufferToFile(surifuzz.sig_file, (uint8_t *)sigaware, len) < 0) {
143 return 0;
144 }
145
146 if (DetectEngineReload(&surifuzz) < 0) {
147 return 0;
148 }
150
152 de_ctx->ref_cnt--;
154 FlowWorkerReplaceDetectCtx(fwd, new_det_ctx);
155
156 DetectEngineThreadCtxDeinit(NULL, old_det_ctx);
157
158 // loop over packets
159 r = FPC_next(&pkts, &header, &pkt);
160 p = PacketGetFromAlloc();
161 if (r <= 0 || header.ts.tv_sec >= INT_MAX - 3600) {
162 goto bail;
163 }
165 p->ts = SCTIME_FROM_TIMEVAL(&header.ts);
166 p->datalink = pkts.datalink;
167 while (r > 0) {
168 if (PacketCopyData(p, pkt, header.caplen) == 0) {
169 // DecodePcapFile
171 if (ecode == TM_ECODE_FAILED) {
172 break;
173 }
175 while (extra_p != NULL) {
176 PacketFreeOrRelease(extra_p);
177 extra_p = PacketDequeueNoLock(&tv.decode_pq);
178 }
180 extra_p = PacketDequeueNoLock(&tv.decode_pq);
181 while (extra_p != NULL) {
182 PacketFreeOrRelease(extra_p);
183 extra_p = PacketDequeueNoLock(&tv.decode_pq);
184 }
185 }
186 r = FPC_next(&pkts, &header, &pkt);
187 if (r <= 0 || header.ts.tv_sec >= INT_MAX - 3600) {
188 goto bail;
189 }
190 PacketRecycle(p);
192 p->ts = SCTIME_FROM_TIMEVAL(&header.ts);
193 p->datalink = pkts.datalink;
194 pcap_cnt++;
195 p->pcap_cnt = pcap_cnt;
196 }
197bail:
198 PacketFree(p);
199 FlowReset();
200
201 return 0;
202}
uint8_t len
int SCConfYamlLoadString(const char *string, size_t len)
Load configuration from a YAML string.
int StatsSetupPrivate(ThreadVars *tv)
Definition counters.c:1209
uint8_t flags
Definition decode-gre.h:0
@ PKT_SRC_WIRE
Definition decode.h:52
int DETECT_TBLSIZE
int DetectEngineReload(const SCInstance *suri)
Reload the detection engine.
DetectEngineCtx * DetectEngineGetCurrent(void)
DetectEngineThreadCtx * DetectEngineThreadCtxInitForReload(ThreadVars *tv, DetectEngineCtx *new_de_ctx, int mt)
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
SigTableElmt * sigmatch_table
#define SIGMATCH_NOOPT
Definition detect.h:1651
#define SIGMATCH_OPTIONAL_OPT
Definition detect.h:1661
FlowQueue * FlowQueueNew(void)
Definition flow-queue.c:35
void FlowWorkerReplaceDetectCtx(void *flow_worker, void *detect_ctx)
void * FlowWorkerGetDetectCtxPtr(void *flow_worker)
void FlowReset(void)
Definition flow.c:673
DetectEngineCtx * de_ctx
DecodeThreadVars * dtv
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
const char * configNoChecksum
Definition confyaml.c:1
ThreadVars tv
SCInstance surifuzz
void * fwd
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition decode.c:628
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition decode.c:804
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition decode.c:258
int PacketCopyData(Packet *p, const uint8_t *pktdata, uint32_t pktlen)
Copy data to Packet payload and set packet length.
Definition decode.c:377
void PacketFreeOrRelease(Packet *p)
Return a packet to where it was allocated.
Definition decode.c:276
void PacketFree(Packet *p)
Return a malloced packet.
Definition decode.c:219
Packet * PacketDequeueNoLock(PacketQueueNoLock *qnl)
void PacketRecycle(Packet *p)
Definition packet.c:150
uint32_t max_pending_packets
Definition suricata.c:183
@ RUNMODE_PCAP_FILE
Definition runmodes.h:30
Structure to hold thread specific data for all decode modules.
Definition decode.h:963
main detection engine ctx
Definition detect.h:932
uint32_t ref_cnt
Definition detect.h:1056
uint64_t pcap_cnt
Definition decode.h:626
SCTime_t ts
Definition decode.h:555
uint8_t pkt_src
Definition decode.h:611
int datalink
Definition decode.h:639
char * sig_file
Definition suricata.h:138
bool sig_file_exclusive
Definition suricata.h:139
int delayed_detect
Definition suricata.h:165
uint16_t flags
Definition detect.h:1450
Per thread variable structure.
Definition threadvars.h:58
PacketQueueNoLock decode_pq
Definition threadvars.h:112
struct FlowQueue_ * flow_queue
Definition threadvars.h:135
TmEcode(* Func)(ThreadVars *, Packet *, void *)
Definition tm-modules.h:56
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition tm-modules.h:51
int InitGlobal(void)
Global initialization common to all runmodes.
Definition suricata.c:2965
void PostConfLoadedDetectSetup(SCInstance *suri)
Definition suricata.c:2625
void PreRunPostPrivsDropInit(const int runmode)
Definition suricata.c:2315
SCRunMode SCRunmodeGet(void)
Get the current run mode.
Definition suricata.c:279
void SCRunmodeSet(SCRunMode run_mode)
Set the current run mode.
Definition suricata.c:284
void GlobalsInitPreConfig(void)
Definition suricata.c:382
int PostConfLoadedSetup(SCInstance *suri)
Definition suricata.c:2716
@ SURICATA_RUNTIME
Definition suricata.h:101
TmModule tmm_modules[TMM_SIZE]
Definition tm-modules.c:29
@ TMM_FLOWWORKER
@ TMM_DECODEPCAPFILE
@ TM_ECODE_FAILED
const char * name
void PacketPoolInit(void)
#define SC_ATOMIC_EXTERN(type, name)
wrapper for referencing an atomic variable declared on another file.
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
TmEcode ConfigSetLogDirectory(const char *name)
Definition util-conf.c:33
#define SCTIME_FROM_TIMEVAL(tv)
Definition util-time.h:79
int TestHelperBufferToFile(const char *name, const uint8_t *data, size_t size)
writes the contents of a buffer into a file
void setenv(const char *name, const char *value, int overwrite)