]>
Commit | Line | Data |
---|---|---|
600b0d7c PA |
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 | ||
240df05a PA |
17 | //rule of thumb constant, so as not to timeout target |
18 | #define PROTO_DETECT_MAX_LEN 1024 | |
600b0d7c PA |
19 | |
20 | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); | |
21 | ||
22 | AppLayerProtoDetectThreadCtx *alpd_tctx = NULL; | |
23 | ||
24 | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) | |
25 | { | |
26 | Flow *f; | |
27 | TcpSession ssn; | |
28 | bool reverse; | |
f51d7d89 PA |
29 | AppProto alproto; |
30 | AppProto alproto2; | |
600b0d7c PA |
31 | |
32 | if (size < HEADER_LEN) { | |
33 | return 0; | |
34 | } | |
35 | ||
36 | if (alpd_tctx == NULL) { | |
37 | //global init | |
38 | InitGlobal(); | |
39 | run_mode = RUNMODE_UNITTEST; | |
40 | MpmTableSetup(); | |
41 | SpmTableSetup(); | |
42 | AppLayerProtoDetectSetup(); | |
43 | AppLayerParserSetup(); | |
44 | AppLayerParserRegisterProtocolParsers(); | |
45 | alpd_tctx = AppLayerProtoDetectGetCtxThread(); | |
46 | } | |
47 | ||
794d9eeb | 48 | f = TestHelperBuildFlow(AF_INET, "1.2.3.4", "5.6.7.8", (data[2] << 8) | data[3], (data[4] << 8) | data[5]); |
600b0d7c PA |
49 | if (f == NULL) { |
50 | return 0; | |
51 | } | |
52 | f->proto = data[1]; | |
53 | memset(&ssn, 0, sizeof(TcpSession)); | |
54 | f->protoctx = &ssn; | |
55 | f->protomap = FlowGetProtoMapping(f->proto); | |
56 | ||
f51d7d89 PA |
57 | alproto = AppLayerProtoDetectGetProto(alpd_tctx, f, data+HEADER_LEN, size-HEADER_LEN, f->proto, data[0], &reverse); |
58 | if (alproto != ALPROTO_UNKNOWN && alproto != ALPROTO_FAILED && f->proto == IPPROTO_TCP) { | |
59 | /* If we find a valid protocol : | |
60 | * check that with smaller input | |
61 | * we find the same protocol or ALPROTO_UNKNOWN. | |
62 | * Otherwise, we have evasion with TCP splitting | |
63 | */ | |
240df05a | 64 | for (size_t i = 0; i < size-HEADER_LEN && i < PROTO_DETECT_MAX_LEN; i++) { |
f51d7d89 PA |
65 | alproto2 = AppLayerProtoDetectGetProto(alpd_tctx, f, data+HEADER_LEN, i, f->proto, data[0], &reverse); |
66 | if (alproto2 != ALPROTO_UNKNOWN && alproto2 != alproto) { | |
80dc6c6f PA |
67 | printf("Failed with input length %" PRIuMAX " versus %" PRIuMAX |
68 | ", found %s instead of %s\n", | |
69 | (uintmax_t)i, (uintmax_t)size - HEADER_LEN, AppProtoToString(alproto2), | |
70 | AppProtoToString(alproto)); | |
71 | printf("Assertion failure: %s-%s\n", AppProtoToString(alproto2), | |
72 | AppProtoToString(alproto)); | |
73 | fflush(stdout); | |
f51d7d89 PA |
74 | abort(); |
75 | } | |
76 | } | |
77 | } | |
794d9eeb | 78 | FlowFree(f); |
600b0d7c PA |
79 | |
80 | return 0; | |
81 | } |