]> git.ipfire.org Git - people/ms/suricata.git/blob - src/tests/fuzz/fuzz_applayerprotodetectgetproto.c
fuzz: check tcp splitting evasions in protocol detection
[people/ms/suricata.git] / src / tests / fuzz / fuzz_applayerprotodetectgetproto.c
1 /**
2 * @file
3 * @author Philippe Antoine <contact@catenacyber.fr>
4 * fuzz target for AppLayerProtoDetectGetProto
5 */
6
7
8 #include "suricata-common.h"
9 #include "app-layer-detect-proto.h"
10 #include "flow-util.h"
11 #include "app-layer-parser.h"
12 #include "util-unittest-helper.h"
13
14
15 #define HEADER_LEN 6
16
17
18 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
19
20 AppLayerProtoDetectThreadCtx *alpd_tctx = NULL;
21
22 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
23 {
24 Flow *f;
25 TcpSession ssn;
26 bool reverse;
27 AppProto alproto;
28 AppProto alproto2;
29
30 if (size < HEADER_LEN) {
31 return 0;
32 }
33
34 if (alpd_tctx == NULL) {
35 //global init
36 InitGlobal();
37 run_mode = RUNMODE_UNITTEST;
38 MpmTableSetup();
39 SpmTableSetup();
40 AppLayerProtoDetectSetup();
41 AppLayerParserSetup();
42 AppLayerParserRegisterProtocolParsers();
43 alpd_tctx = AppLayerProtoDetectGetCtxThread();
44 }
45
46 f = UTHBuildFlow(AF_INET, "1.2.3.4", "5.6.7.8", (data[2] << 8) | data[3], (data[4] << 8) | data[5]);
47 if (f == NULL) {
48 return 0;
49 }
50 f->proto = data[1];
51 memset(&ssn, 0, sizeof(TcpSession));
52 f->protoctx = &ssn;
53 f->protomap = FlowGetProtoMapping(f->proto);
54
55 alproto = AppLayerProtoDetectGetProto(alpd_tctx, f, data+HEADER_LEN, size-HEADER_LEN, f->proto, data[0], &reverse);
56 if (alproto != ALPROTO_UNKNOWN && alproto != ALPROTO_FAILED && f->proto == IPPROTO_TCP) {
57 /* If we find a valid protocol :
58 * check that with smaller input
59 * we find the same protocol or ALPROTO_UNKNOWN.
60 * Otherwise, we have evasion with TCP splitting
61 */
62 for (size_t i = 0; i < size-HEADER_LEN; i++) {
63 alproto2 = AppLayerProtoDetectGetProto(alpd_tctx, f, data+HEADER_LEN, i, f->proto, data[0], &reverse);
64 if (alproto2 != ALPROTO_UNKNOWN && alproto2 != alproto) {
65 printf("Assertion failure : With input length %"PRIuMAX", found %s instead of %s\n", (uintmax_t) i, AppProtoToString(alproto2), AppProtoToString(alproto));
66 abort();
67 }
68 }
69 }
70 UTHFreeFlow(f);
71
72 return 0;
73 }