suricata
fuzz_applayerprotodetectgetproto.c
Go to the documentation of this file.
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 "suricata.h"
10 #include "app-layer-detect-proto.h"
11 #include "flow-util.h"
12 #include "app-layer-parser.h"
13 #include "util-unittest-helper.h"
14 #include "conf-yaml-loader.h"
15 
16 #define HEADER_LEN 6
17 
18 //rule of thumb constant, so as not to timeout target
19 #define PROTO_DETECT_MAX_LEN 1024
20 
21 #include "confyaml.c"
22 
23 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
24 
26 SC_ATOMIC_EXTERN(unsigned int, engine_stage);
27 
28 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
29 {
30  Flow *f;
31  TcpSession ssn;
32  bool reverse;
33  AppProto alproto;
34  AppProto alproto2;
35 
36  if (alpd_tctx == NULL) {
37  //global init
38  InitGlobal();
41  abort();
42  }
43  MpmTableSetup();
44  SpmTableSetup();
50  SC_ATOMIC_SET(engine_stage, SURICATA_RUNTIME);
51  }
52 
53  if (size < HEADER_LEN) {
54  return 0;
55  }
56 
57  f = TestHelperBuildFlow(AF_INET, "1.2.3.4", "5.6.7.8", (uint16_t)((data[2] << 8) | data[3]),
58  (uint16_t)((data[4] << 8) | data[5]));
59  if (f == NULL) {
60  return 0;
61  }
62  f->proto = data[1];
63  memset(&ssn, 0, sizeof(TcpSession));
64  f->protoctx = &ssn;
66 
67  uint8_t flags = STREAM_TOCLIENT;
68  if (data[0] & STREAM_TOSERVER) {
69  flags = STREAM_TOSERVER;
70  }
72  alpd_tctx, f, data + HEADER_LEN, size - HEADER_LEN, f->proto, flags, &reverse);
73  if (alproto != ALPROTO_UNKNOWN && alproto != ALPROTO_FAILED && f->proto == IPPROTO_TCP) {
74  /* If we find a valid protocol at the start of a stream :
75  * check that with smaller input
76  * we find the same protocol or ALPROTO_UNKNOWN.
77  * Otherwise, we have evasion with TCP splitting
78  */
79  for (size_t i = 0; i < size-HEADER_LEN && i < PROTO_DETECT_MAX_LEN; i++) {
80  // reset detection at each try cf probing_parser_toserver_alproto_masks
82  alproto2 = AppLayerProtoDetectGetProto(
83  alpd_tctx, f, data + HEADER_LEN, i, f->proto, flags, &reverse);
84  if (alproto2 != ALPROTO_UNKNOWN && alproto2 != alproto) {
85  printf("Failed with input length %" PRIuMAX " versus %" PRIuMAX
86  ", found %s instead of %s\n",
87  (uintmax_t)i, (uintmax_t)size - HEADER_LEN, AppProtoToString(alproto2),
88  AppProtoToString(alproto));
89  printf("Assertion failure: %s-%s\n", AppProtoToString(alproto2),
90  AppProtoToString(alproto));
91  fflush(stdout);
92  abort();
93  }
94  }
95  }
96  FlowFree(f);
97 
98  return 0;
99 }
AppLayerProtoDetectSetup
int AppLayerProtoDetectSetup(void)
The first function to be called. This initializes a global protocol detection context.
Definition: app-layer-detect-proto.c:1699
RUNMODE_UNITTEST
@ RUNMODE_UNITTEST
Definition: runmodes.h:41
flow-util.h
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:386
Flow_::proto
uint8_t proto
Definition: flow.h:373
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:81
HEADER_LEN
#define HEADER_LEN
Definition: fuzz_applayerprotodetectgetproto.c:16
Flow_
Flow data structure.
Definition: flow.h:351
Flow_::protomap
uint8_t protomap
Definition: flow.h:445
AppProtoToString
const char * AppProtoToString(AppProto alproto)
Maps the ALPROTO_*, to its string equivalent.
Definition: app-layer-protos.c:75
SCRunmodeSet
void SCRunmodeSet(int run_mode)
Set the current run mode.
Definition: suricata.c:268
SURICATA_RUNTIME
@ SURICATA_RUNTIME
Definition: suricata.h:96
Flow_::protoctx
void * protoctx
Definition: flow.h:441
util-unittest-helper.h
AppLayerParserRegisterProtocolParsers
void AppLayerParserRegisterProtocolParsers(void)
Definition: app-layer-parser.c:1720
app-layer-detect-proto.h
PROTO_DETECT_MAX_LEN
#define PROTO_DETECT_MAX_LEN
Definition: fuzz_applayerprotodetectgetproto.c:19
AppLayerProtoDetectThreadCtx_
The app layer protocol detection thread context.
Definition: app-layer-detect-proto.c:174
EngineModeSetIDS
void EngineModeSetIDS(void)
Definition: suricata.c:248
SpmTableSetup
void SpmTableSetup(void)
Definition: util-spm.c:122
LLVMFuzzerTestOneInput
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
Definition: fuzz_applayerprotodetectgetproto.c:28
AppLayerProtoDetectReset
void AppLayerProtoDetectReset(Flow *f)
Reset proto detect for flow.
Definition: app-layer-detect-proto.c:1847
alpd_tctx
AppLayerProtoDetectThreadCtx * alpd_tctx
Definition: fuzz_applayerprotodetectgetproto.c:25
ConfYamlLoadString
int ConfYamlLoadString(const char *string, size_t len)
Load configuration from a YAML string.
Definition: conf-yaml-loader.c:522
app-layer-parser.h
AppLayerParserSetup
int AppLayerParserSetup(void)
Definition: app-layer-parser.c:254
FlowGetProtoMapping
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:97
conf-yaml-loader.h
confyaml.c
MpmTableSetup
void MpmTableSetup(void)
Definition: util-mpm.c:225
flags
uint8_t flags
Definition: decode-gre.h:0
suricata-common.h
FlowFree
void FlowFree(Flow *f)
cleanup & free the memory of a flow
Definition: flow-util.c:82
configNoChecksum
const char configNoChecksum[]
Definition: confyaml.c:1
SC_ATOMIC_EXTERN
SC_ATOMIC_EXTERN(unsigned int, engine_stage)
AppLayerProtoDetectGetProto
AppProto AppLayerProtoDetectGetProto(AppLayerProtoDetectThreadCtx *tctx, Flow *f, const uint8_t *buf, uint32_t buflen, uint8_t ipproto, uint8_t flags, bool *reverse_flow)
Returns the app layer protocol given a buffer.
Definition: app-layer-detect-proto.c:1396
AppLayerProtoDetectGetCtxThread
AppLayerProtoDetectThreadCtx * AppLayerProtoDetectGetCtxThread(void)
Inits and returns an app layer protocol detection thread context.
Definition: app-layer-detect-proto.c:1941
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
ALPROTO_FAILED
@ ALPROTO_FAILED
Definition: app-layer-protos.h:71
suricata.h
TestHelperBuildFlow
Flow * TestHelperBuildFlow(int family, const char *src, const char *dst, Port sp, Port dp)
Definition: util-unittest-helper.c:52
InitGlobal
int InitGlobal(void)
Global initialization common to all runmodes.
Definition: suricata.c:2875
TcpSession_
Definition: stream-tcp-private.h:283