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 
42 /* stateful processing of data as packets. Because AFL in case of a
43  * crash will only safe the last input, we dump all the inputs to a
44  * directory 'dump' with a unique timestamp for the serie and an
45  * incrementing 'id' so that we can 'replay' it in
46  * DecoderParseDataFromFileSerie().
47  */
48 int DecoderParseDataFromFile(char *filename, DecoderFunc Decoder) {
49  uint8_t buffer[65536];
50 
51  struct timeval ts;
52  memset(&ts, 0, sizeof(ts));
53  gettimeofday(&ts, NULL);
54 
55  uint32_t cnt = 0;
56 
57  DefragInit();
59 
60  ThreadVars tv;
61  memset(&tv, 0, sizeof(tv));
64  StatsSetupPrivate(&tv);
65  PacketQueue pq;
66  memset(&pq, 0, sizeof(pq));
67 
68 #ifdef AFLFUZZ_PERSISTANT_MODE
69  while (__AFL_LOOP(1000)) {
70  /* reset state */
71  memset(buffer, 0, sizeof(buffer));
72 #endif /* AFLFUZZ_PERSISTANT_MODE */
73 
74 
75  FILE *fp = fopen(filename, "r");
76  BUG_ON(fp == NULL);
77 
78  size_t size = fread(&buffer, 1, sizeof(buffer), fp);
79  char outfilename[256];
80  snprintf(outfilename, sizeof(outfilename), "dump/%u-%u.%u",
81  (unsigned int)ts.tv_sec, (unsigned int)ts.tv_usec, cnt);
82  FILE *out_fp = fopen(outfilename, "w");
83  BUG_ON(out_fp == NULL);
84  (void)fwrite(buffer, size, 1, out_fp);
85  fclose(out_fp);
86 
88  if (p != NULL) {
89  PacketSetData(p, buffer, size);
90  (void) Decoder (&tv, dtv, p, buffer, size, &pq);
91  while (1) {
92  Packet *extra_p = PacketDequeue(&pq);
93  if (unlikely(extra_p == NULL))
94  break;
95  PacketFree(extra_p);
96  }
97  PacketFree(p);
98  }
99  fclose(fp);
100  cnt++;
101 
102 #ifdef AFLFUZZ_PERSISTANT_MODE
103  }
104 #endif /* AFLFUZZ_PERSISTANT_MODE */
105 
106  /* if we get here there was no crash, so we can remove our files */
107  uint32_t x = 0;
108  for (x = 0; x < cnt; x++) {
109  char rmfilename[256];
110  snprintf(rmfilename, sizeof(rmfilename), "dump/%u-%u.%u",
111  (unsigned int)ts.tv_sec, (unsigned int)ts.tv_usec, x);
112  unlink(rmfilename);
113  }
114 
115  DecodeThreadVarsFree(&tv, dtv);
116  FlowShutdown();
117  DefragDestroy();
118  return 0;
119 }
120 
121 /* load a serie of files generated by DecoderParseDataFromFile() in
122  * the same order as it was produced. */
123 int DecoderParseDataFromFileSerie(char *fileprefix, DecoderFunc Decoder)
124 {
125  uint8_t buffer[65536];
126  uint32_t cnt = 0;
127 
128  DefragInit();
130  ThreadVars tv;
131  memset(&tv, 0, sizeof(tv));
133  DecodeRegisterPerfCounters(dtv, &tv);
134  StatsSetupPrivate(&tv);
135  PacketQueue pq;
136  memset(&pq, 0, sizeof(pq));
137 
138  char filename[256];
139  snprintf(filename, sizeof(filename), "dump/%s.%u", fileprefix, cnt);
140  FILE *fp;
141  while ((fp = fopen(filename, "r")) != NULL)
142  {
143  memset(buffer, 0, sizeof(buffer));
144 
145  size_t size = fread(&buffer, 1, sizeof(buffer), fp);
146 
147  Packet *p = PacketGetFromAlloc();
148  if (p != NULL) {
149  PacketSetData(p, buffer, size);
150  (void) Decoder (&tv, dtv, p, buffer, size, &pq);
151  while (1) {
152  Packet *extra_p = PacketDequeue(&pq);
153  if (unlikely(extra_p == NULL))
154  break;
155  PacketFree(extra_p);
156  }
157  PacketFree(p);
158  }
159  fclose(fp);
160  cnt++;
161  snprintf(filename, sizeof(filename), "dump/%s.%u", fileprefix, cnt);
162  }
163  DecodeThreadVarsFree(&tv, dtv);
164  FlowShutdown();
165  DefragDestroy();
166  return 0;
167 }
168 #endif /* AFLFUZZ_DECODER */
169 
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:570
#define BUG_ON(x)
#define unlikely(expr)
Definition: util-optimize.h:35
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:431
#define FLOW_QUIET
Definition: flow.h:37
void PacketFree(Packet *p)
Return a malloced packet.
Definition: decode.c:101
void DefragDestroy(void)
Definition: defrag.c:1067
int(* Decoder)(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint32_t, PacketQueue *)
Structure to hold thread specific data for all decode modules.
Definition: decode.h:642
void DefragInit(void)
Definition: defrag.c:1045
int PacketSetData(Packet *p, uint8_t *pktdata, uint32_t pktlen)
Set data for Packet and set length when zeo copy is used.
Definition: decode.c:616
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:599
uint64_t ts
int StatsSetupPrivate(ThreadVars *tv)
Definition: counters.c:1201
Packet * PacketDequeue(PacketQueue *q)
Definition: packet-queue.c:167
Per thread variable structure.
Definition: threadvars.h:57
void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv)
Definition: decode.c:596
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:140
void FlowInitConfig(char quiet)
initialize the configuration
Definition: flow.c:444