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, PacketQueue *pq)
43 {
44  return DecodeIPV4(tv, dtv, p, pkt, (uint16_t)len, pq);
45 }
46 int AFLDecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
47  const uint8_t *pkt, uint32_t len, PacketQueue *pq)
48 {
49  return DecodeIPV6(tv, dtv, p, pkt, (uint16_t)len, pq);
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  uint8_t buffer[65536];
60 
61  struct timeval ts;
62  memset(&ts, 0, sizeof(ts));
63  gettimeofday(&ts, NULL);
64 
65  uint32_t cnt = 0;
66 
67  DefragInit();
69 
70  ThreadVars tv;
71  memset(&tv, 0, sizeof(tv));
74  StatsSetupPrivate(&tv);
75  PacketQueue pq;
76  memset(&pq, 0, sizeof(pq));
77 
78 #ifdef AFLFUZZ_PERSISTANT_MODE
79  while (__AFL_LOOP(1000)) {
80  /* reset state */
81  memset(buffer, 0, sizeof(buffer));
82 #endif /* AFLFUZZ_PERSISTANT_MODE */
83 
84 
85  FILE *fp = fopen(filename, "r");
86  BUG_ON(fp == NULL);
87 
88  size_t size = fread(&buffer, 1, sizeof(buffer), fp);
89  char outfilename[256];
90  snprintf(outfilename, sizeof(outfilename), "dump/%u-%u.%u",
91  (unsigned int)ts.tv_sec, (unsigned int)ts.tv_usec, cnt);
92  FILE *out_fp = fopen(outfilename, "w");
93  BUG_ON(out_fp == NULL);
94  (void)fwrite(buffer, size, 1, out_fp);
95  fclose(out_fp);
96 
98  if (p != NULL) {
99  PacketSetData(p, buffer, size);
100  (void) Decoder (&tv, dtv, p, buffer, size, &pq);
101  while (1) {
102  Packet *extra_p = PacketDequeue(&pq);
103  if (unlikely(extra_p == NULL))
104  break;
105  PacketFree(extra_p);
106  }
107  PacketFree(p);
108  }
109  fclose(fp);
110  cnt++;
111 
112 #ifdef AFLFUZZ_PERSISTANT_MODE
113  }
114 #endif /* AFLFUZZ_PERSISTANT_MODE */
115 
116  /* if we get here there was no crash, so we can remove our files */
117  uint32_t x = 0;
118  for (x = 0; x < cnt; x++) {
119  char rmfilename[256];
120  snprintf(rmfilename, sizeof(rmfilename), "dump/%u-%u.%u",
121  (unsigned int)ts.tv_sec, (unsigned int)ts.tv_usec, x);
122  unlink(rmfilename);
123  }
124 
125  DecodeThreadVarsFree(&tv, dtv);
126  FlowShutdown();
127  DefragDestroy();
128  StatsThreadCleanup(&tv);
130  return 0;
131 }
132 
133 /* load a serie of files generated by DecoderParseDataFromFile() in
134  * the same order as it was produced. */
135 int DecoderParseDataFromFileSerie(char *fileprefix, DecoderFunc Decoder)
136 {
137  uint8_t buffer[65536];
138  uint32_t cnt = 0;
139 
140  DefragInit();
142  ThreadVars tv;
143  memset(&tv, 0, sizeof(tv));
145  DecodeRegisterPerfCounters(dtv, &tv);
146  StatsSetupPrivate(&tv);
147  PacketQueue pq;
148  memset(&pq, 0, sizeof(pq));
149 
150  char filename[256];
151  snprintf(filename, sizeof(filename), "dump/%s.%u", fileprefix, cnt);
152  FILE *fp;
153  while ((fp = fopen(filename, "r")) != NULL)
154  {
155  memset(buffer, 0, sizeof(buffer));
156 
157  size_t size = fread(&buffer, 1, sizeof(buffer), fp);
158 
159  Packet *p = PacketGetFromAlloc();
160  if (p != NULL) {
161  PacketSetData(p, buffer, size);
162  (void) Decoder (&tv, dtv, p, buffer, size, &pq);
163  while (1) {
164  Packet *extra_p = PacketDequeue(&pq);
165  if (unlikely(extra_p == NULL))
166  break;
167  PacketFree(extra_p);
168  }
169  PacketFree(p);
170  }
171  fclose(fp);
172  cnt++;
173  snprintf(filename, sizeof(filename), "dump/%s.%u", fileprefix, cnt);
174  }
175  DecodeThreadVarsFree(&tv, dtv);
176  FlowShutdown();
177  DefragDestroy();
178  return 0;
179 }
180 #endif /* AFLFUZZ_DECODER */
181 
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:614
void StatsReleaseResources()
Releases the resources alloted by the Stats API.
Definition: counters.c:1256
int(* DecoderFunc)(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len, PacketQueue *pq)
Definition: decode.h:955
#define BUG_ON(x)
#define unlikely(expr)
Definition: util-optimize.h:35
void StatsThreadCleanup(ThreadVars *tv)
Definition: counters.c:1297
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:474
#define FLOW_QUIET
Definition: flow.h:38
void PacketFree(Packet *p)
Return a malloced packet.
Definition: decode.c:102
void DefragDestroy(void)
Definition: defrag.c:1090
Structure to hold thread specific data for all decode modules.
Definition: decode.h:632
void DefragInit(void)
Definition: defrag.c:1068
int PacketSetData(Packet *p, const uint8_t *pktdata, uint32_t pktlen)
Set data for Packet and set length when zeo copy is used.
Definition: decode.c:653
int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len, PacketQueue *pq)
Definition: decode-ipv6.c:585
int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len, PacketQueue *pq)
Definition: decode-ipv4.c:532
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:670
uint64_t ts
int StatsSetupPrivate(ThreadVars *tv)
Definition: counters.c:1198
Packet * PacketDequeue(PacketQueue *q)
Definition: packet-queue.c:167
uint8_t len
Per thread variable structure.
Definition: threadvars.h:57
void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv)
Definition: decode.c:633
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:141
void FlowInitConfig(char quiet)
initialize the configuration
Definition: flow.c:515