]> git.ipfire.org Git - people/ms/suricata.git/blame - src/tests/fuzz/fuzz_applayerprotodetectgetproto.c
fuzz: restrict flags passed to AppLayerProtoDetectGetProto
[people/ms/suricata.git] / src / tests / fuzz / fuzz_applayerprotodetectgetproto.c
CommitLineData
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
20int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
21
22AppLayerProtoDetectThreadCtx *alpd_tctx = NULL;
23
24int 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++) {
f4449d3f
PA
71 alproto2 = AppLayerProtoDetectGetProto(
72 alpd_tctx, f, data + HEADER_LEN, i, f->proto, flags, &reverse);
f51d7d89 73 if (alproto2 != ALPROTO_UNKNOWN && alproto2 != alproto) {
80dc6c6f
PA
74 printf("Failed with input length %" PRIuMAX " versus %" PRIuMAX
75 ", found %s instead of %s\n",
76 (uintmax_t)i, (uintmax_t)size - HEADER_LEN, AppProtoToString(alproto2),
77 AppProtoToString(alproto));
78 printf("Assertion failure: %s-%s\n", AppProtoToString(alproto2),
79 AppProtoToString(alproto));
80 fflush(stdout);
f51d7d89
PA
81 abort();
82 }
83 }
84 }
794d9eeb 85 FlowFree(f);
600b0d7c
PA
86
87 return 0;
88}