suricata
decode-afl.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2017 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 #include "suricata-common.h"
19 #include "suricata.h"
20 #include "conf.h"
21 #include "decode.h"
22 #include "util-debug.h"
23 #include "util-mem.h"
24 #include "app-layer-detect-proto.h"
25 #include "app-layer.h"
26 #include "tm-threads.h"
27 #include "util-error.h"
28 #include "util-print.h"
29 #include "tmqh-packetpool.h"
30 #include "util-profiling.h"
31 #include "pkt-var.h"
32 #include "util-mpm-ac.h"
33 
34 #include "output.h"
35 #include "output-flow.h"
36 
37 #include "defrag.h"
38 #include "flow.h"
39 
40 #ifdef AFLFUZZ_DECODER
41 int AFLDecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
42  const uint8_t *pkt, uint32_t len)
43 {
44  return DecodeIPV4(tv, dtv, p, pkt, (uint16_t)len);
45 }
46 int AFLDecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
47  const uint8_t *pkt, uint32_t len)
48 {
49  return DecodeIPV6(tv, dtv, p, pkt, (uint16_t)len);
50 }
51 
52 /* stateful processing of data as packets. Because AFL in case of a
53  * crash will only safe the last input, we dump all the inputs to a
54  * directory 'dump' with a unique timestamp for the serie and an
55  * incrementing 'id' so that we can 'replay' it in
56  * DecoderParseDataFromFileSerie().
57  */
58 int DecoderParseDataFromFile(char *filename, DecoderFunc Decoder)
59 {
60  bool do_dump = (getenv("SC_AFL_DUMP_FILES") != NULL);
61  uint8_t buffer[65536];
62  struct timeval ts;
63  memset(&ts, 0, sizeof(ts));
64  gettimeofday(&ts, NULL);
65 
66  uint32_t cnt = 0;
67 
68  DefragInit();
70 
71  ThreadVars tv;
72  memset(&tv, 0, sizeof(tv));
75  StatsSetupPrivate(&tv);
76  PacketQueue pq;
77  memset(&pq, 0, sizeof(pq));
78 
79 #ifdef AFLFUZZ_PERSISTANT_MODE
80  while (__AFL_LOOP(1000)) {
81  /* reset state */
82  memset(buffer, 0, sizeof(buffer));
83 #endif /* AFLFUZZ_PERSISTANT_MODE */
84 
85  FILE *fp = fopen(filename, "r");
86  BUG_ON(fp == NULL);
87 
88  size_t size = fread(&buffer, 1, sizeof(buffer), fp);
89  if (do_dump) {
90  char outfilename[256];
91  snprintf(outfilename, sizeof(outfilename), "dump/%u-%u.%u",
92  (unsigned int)ts.tv_sec, (unsigned int)ts.tv_usec, cnt);
93  FILE *out_fp = fopen(outfilename, "w");
94  BUG_ON(out_fp == NULL);
95  (void)fwrite(buffer, size, 1, out_fp);
96  fclose(out_fp);
97  }
98 
100  if (p != NULL) {
101  PacketSetData(p, buffer, size);
102  (void) Decoder (&tv, dtv, p, buffer, size);
103  while (1) {
104  Packet *extra_p = PacketDequeueNoLock(&tv.decode_pq);
105  if (unlikely(extra_p == NULL))
106  break;
107  PacketFree(extra_p);
108  }
109  PacketFree(p);
110  }
111  fclose(fp);
112  cnt++;
113 
114 #ifdef AFLFUZZ_PERSISTANT_MODE
115  }
116 #endif /* AFLFUZZ_PERSISTANT_MODE */
117 
118  /* if we get here there was no crash, so we can remove our files */
119  if (do_dump) {
120  for (uint32_t x = 0; x < cnt; x++) {
121  char rmfilename[256];
122  snprintf(rmfilename, sizeof(rmfilename), "dump/%u-%u.%u",
123  (unsigned int)ts.tv_sec, (unsigned int)ts.tv_usec, x);
124  unlink(rmfilename);
125  }
126  }
127  DecodeThreadVarsFree(&tv, dtv);
128  FlowShutdown();
129  DefragDestroy();
130  StatsThreadCleanup(&tv);
132  return 0;
133 }
134 
135 /* load a serie of files generated by DecoderParseDataFromFile() in
136  * the same order as it was produced. */
137 int DecoderParseDataFromFileSerie(char *fileprefix, DecoderFunc Decoder)
138 {
139  uint8_t buffer[65536];
140  uint32_t cnt = 0;
141 
142  DefragInit();
144  ThreadVars tv;
145  memset(&tv, 0, sizeof(tv));
147  DecodeRegisterPerfCounters(dtv, &tv);
148  StatsSetupPrivate(&tv);
149  PacketQueue pq;
150  memset(&pq, 0, sizeof(pq));
151 
152  char filename[256];
153  snprintf(filename, sizeof(filename), "dump/%s.%u", fileprefix, cnt);
154  FILE *fp;
155  while ((fp = fopen(filename, "r")) != NULL)
156  {
157  memset(buffer, 0, sizeof(buffer));
158 
159  size_t size = fread(&buffer, 1, sizeof(buffer), fp);
160 
161  Packet *p = PacketGetFromAlloc();
162  if (p != NULL) {
163  PacketSetData(p, buffer, size);
164  (void) Decoder (&tv, dtv, p, buffer, size);
165  while (1) {
166  Packet *extra_p = PacketDequeueNoLock(&tv.decode_pq);
167  if (unlikely(extra_p == NULL))
168  break;
169  PacketFree(extra_p);
170  }
171  PacketFree(p);
172  }
173  fclose(fp);
174  cnt++;
175  snprintf(filename, sizeof(filename), "dump/%s.%u", fileprefix, cnt);
176  }
177  DecodeThreadVarsFree(&tv, dtv);
178  FlowShutdown();
179  DefragDestroy();
180  return 0;
181 }
182 #endif /* AFLFUZZ_DECODER */
183 
DefragDestroy
void DefragDestroy(void)
Definition: defrag.c:1090
tm-threads.h
len
uint8_t len
Definition: app-layer-dnp3.h:4
ts
uint64_t ts
Definition: source-erf-file.c:2
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
PacketQueue_
simple fifo queue for packets with mutex and cond Calling the mutex or triggering the cond is respons...
Definition: packet-queue.h:47
FlowInitConfig
void FlowInitConfig(char quiet)
initialize the configuration
Definition: flow.c:529
DecoderFunc
int(* DecoderFunc)(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode.h:947
StatsSetupPrivate
int StatsSetupPrivate(ThreadVars *tv)
Definition: counters.c:1198
tmqh-packetpool.h
DecodeRegisterPerfCounters
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:477
app-layer-detect-proto.h
decode.h
util-debug.h
util-error.h
PacketDequeueNoLock
Packet * PacketDequeueNoLock(PacketQueueNoLock *qnl)
Definition: packet-queue.c:206
util-print.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
pkt-var.h
PacketFree
void PacketFree(Packet *p)
Return a malloced packet.
Definition: decode.c:105
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:265
util-profiling.h
Packet_
Definition: decode.h:408
DecodeIPV6
int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-ipv6.c:580
conf.h
output-flow.h
util-mpm-ac.h
defrag.h
util-mem.h
DecodeThreadVarsFree
void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv)
Definition: decode.c:636
suricata-common.h
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:684
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:144
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:622
DecodeThreadVarsAlloc
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:617
PacketSetData
int PacketSetData(Packet *p, const uint8_t *pktdata, uint32_t pktlen)
Set data for Packet and set length when zero copy is used.
Definition: decode.c:656
ThreadVars_::decode_pq
PacketQueueNoLock decode_pq
Definition: threadvars.h:109
suricata.h
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:38
flow.h
DecodeIPV4
int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-ipv4.c:517
StatsReleaseResources
void StatsReleaseResources()
Releases the resources alloted by the Stats API.
Definition: counters.c:1256
StatsThreadCleanup
void StatsThreadCleanup(ThreadVars *tv)
Definition: counters.c:1297
output.h
DefragInit
void DefragInit(void)
Definition: defrag.c:1068
app-layer.h