]>
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 | ||
05f9b3ff PA |
57 | uint8_t flags = STREAM_TOCLIENT; |
58 | if (data[0] & STREAM_TOSERVER) { | |
59 | flags = STREAM_TOSERVER; | |
60 | } | |
61 | alproto = AppLayerProtoDetectGetProto( | |
62 | alpd_tctx, f, data + HEADER_LEN, size - HEADER_LEN, f->proto, flags, &reverse); | |
52ea3fc7 PA |
63 | if (alproto != ALPROTO_UNKNOWN && alproto != ALPROTO_FAILED && f->proto == IPPROTO_TCP && |
64 | (data[0] & STREAM_MIDSTREAM) == 0) { | |
65 | /* If we find a valid protocol at the start of a stream : | |
f51d7d89 PA |
66 | * check that with smaller input |
67 | * we find the same protocol or ALPROTO_UNKNOWN. | |
68 | * Otherwise, we have evasion with TCP splitting | |
69 | */ | |
240df05a | 70 | for (size_t i = 0; i < size-HEADER_LEN && i < PROTO_DETECT_MAX_LEN; i++) { |
f51d7d89 PA |
71 | alproto2 = AppLayerProtoDetectGetProto(alpd_tctx, f, data+HEADER_LEN, i, f->proto, data[0], &reverse); |
72 | if (alproto2 != ALPROTO_UNKNOWN && alproto2 != alproto) { | |
80dc6c6f PA |
73 | printf("Failed with input length %" PRIuMAX " versus %" PRIuMAX |
74 | ", found %s instead of %s\n", | |
75 | (uintmax_t)i, (uintmax_t)size - HEADER_LEN, AppProtoToString(alproto2), | |
76 | AppProtoToString(alproto)); | |
77 | printf("Assertion failure: %s-%s\n", AppProtoToString(alproto2), | |
78 | AppProtoToString(alproto)); | |
79 | fflush(stdout); | |
f51d7d89 PA |
80 | abort(); |
81 | } | |
82 | } | |
83 | } | |
794d9eeb | 84 | FlowFree(f); |
600b0d7c PA |
85 | |
86 | return 0; | |
87 | } |