From: Victor Julien Date: Mon, 23 Jan 2023 18:41:45 +0000 (+0100) Subject: frames: enable only used frames X-Git-Tag: suricata-7.0.0-rc1~107 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F8429%2Fhead;p=thirdparty%2Fsuricata.git frames: enable only used frames Enable only frames that are actually used. Ticket: #4979. --- diff --git a/src/app-layer-frames.c b/src/app-layer-frames.c index bebb4ad500..4b1ddde6b1 100644 --- a/src/app-layer-frames.c +++ b/src/app-layer-frames.c @@ -30,6 +30,42 @@ #include "app-layer-frames.h" #include "app-layer-parser.h" +struct FrameConfig { + SC_ATOMIC_DECLARE(uint64_t, types); +}; +static struct FrameConfig frame_config[ALPROTO_MAX]; + +void FrameConfigInit(void) +{ + for (AppProto p = 0; p < ALPROTO_MAX; p++) { + SC_ATOMIC_INIT(frame_config[p].types); + } +} + +void FrameConfigEnableAll(void) +{ + const uint64_t bits = UINT64_MAX; + for (AppProto p = 0; p < ALPROTO_MAX; p++) { + struct FrameConfig *fc = &frame_config[p]; + SC_ATOMIC_OR(fc->types, bits); + } +} + +void FrameConfigEnable(const AppProto p, const uint8_t type) +{ + const uint64_t bits = BIT_U64(type); + struct FrameConfig *fc = &frame_config[p]; + SC_ATOMIC_OR(fc->types, bits); +} + +static inline bool FrameConfigTypeIsEnabled(const AppProto p, const uint8_t type) +{ + struct FrameConfig *fc = &frame_config[p]; + const uint64_t bits = BIT_U64(type); + const bool enabled = (SC_ATOMIC_GET(fc->types) & bits) != 0; + return enabled; +} + static void FrameDebug(const char *prefix, const Frames *frames, const Frame *frame) { #ifdef DEBUG @@ -383,7 +419,10 @@ Frame *AppLayerFrameNewByPointer(Flow *f, const StreamSlice *stream_slice, SCLogDebug("frame_start:%p stream_slice->input:%p stream_slice->offset:%" PRIu64, frame_start, stream_slice->input, stream_slice->offset); - /* workarounds for many (unit|fuzz)tests not handling TCP data properly */ + if (!(FrameConfigTypeIsEnabled(f->alproto, frame_type))) + return NULL; + + /* workarounds for many (unit|fuzz)tests not handling TCP data properly */ #if defined(UNITTESTS) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) if (f->proto == IPPROTO_TCP && f->protoctx == NULL) return NULL; @@ -430,6 +469,9 @@ static Frame *AppLayerFrameUdp(Flow *f, const StreamSlice *stream_slice, { BUG_ON(f->proto != IPPROTO_UDP); + if (!(FrameConfigTypeIsEnabled(f->alproto, frame_type))) + return NULL; + FramesContainer *frames_container = AppLayerFramesSetupContainer(f); if (frames_container == NULL) return NULL; @@ -453,7 +495,10 @@ static Frame *AppLayerFrameUdp(Flow *f, const StreamSlice *stream_slice, Frame *AppLayerFrameNewByRelativeOffset(Flow *f, const StreamSlice *stream_slice, const uint32_t frame_start_rel, const int64_t len, int dir, uint8_t frame_type) { - /* workarounds for many (unit|fuzz)tests not handling TCP data properly */ + if (!(FrameConfigTypeIsEnabled(f->alproto, frame_type))) + return NULL; + + /* workarounds for many (unit|fuzz)tests not handling TCP data properly */ #if defined(UNITTESTS) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) if (f->proto == IPPROTO_TCP && f->protoctx == NULL) return NULL; @@ -510,7 +555,10 @@ void AppLayerFrameDump(Flow *f) Frame *AppLayerFrameNewByAbsoluteOffset(Flow *f, const StreamSlice *stream_slice, const uint64_t frame_start, const int64_t len, int dir, uint8_t frame_type) { - /* workarounds for many (unit|fuzz)tests not handling TCP data properly */ + if (!(FrameConfigTypeIsEnabled(f->alproto, frame_type))) + return NULL; + + /* workarounds for many (unit|fuzz)tests not handling TCP data properly */ #if defined(UNITTESTS) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) if (f->proto == IPPROTO_TCP && f->protoctx == NULL) return NULL; diff --git a/src/app-layer-frames.h b/src/app-layer-frames.h index 98ddefede7..ea24e1b5dc 100644 --- a/src/app-layer-frames.h +++ b/src/app-layer-frames.h @@ -26,7 +26,8 @@ #include "rust.h" -#define FRAME_STREAM_TYPE 255 +/** max 63 to fit the 64 bit per protocol space */ +#define FRAME_STREAM_TYPE 63 /** always the first frame to be created. TODO but what about protocol upgrades? */ #define FRAME_STREAM_ID 1 @@ -102,4 +103,8 @@ void AppLayerFramesSlide(Flow *f, const uint32_t slide, const uint8_t direction) FramesContainer *AppLayerFramesGetContainer(Flow *f); FramesContainer *AppLayerFramesSetupContainer(Flow *f); +void FrameConfigInit(void); +void FrameConfigEnableAll(void); +void FrameConfigEnable(const AppProto p, const uint8_t type); + #endif diff --git a/src/detect-frame.c b/src/detect-frame.c index 8df5df9366..c74c145a07 100644 --- a/src/detect-frame.c +++ b/src/detect-frame.c @@ -141,6 +141,7 @@ static int DetectFrameSetup(DetectEngineCtx *de_ctx, Signature *s, const char *s if (DetectBufferSetActiveList(s, buffer_id) < 0) return -1; + FrameConfigEnable(keyword_alproto, frame_type); return 0; } diff --git a/src/output-json-frame.c b/src/output-json-frame.c index 68ecd95d48..d23ba92ac3 100644 --- a/src/output-json-frame.c +++ b/src/output-json-frame.c @@ -489,6 +489,8 @@ static OutputInitResult JsonFrameLogInitCtxSub(ConfNode *conf, OutputCtx *parent output_ctx->data = json_output_ctx; output_ctx->DeInit = JsonFrameLogDeInitCtxSub; + FrameConfigEnableAll(); + result.ctx = output_ctx; result.ok = true; return result; diff --git a/src/suricata.c b/src/suricata.c index 4828a89386..ba7e8e5f2e 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -336,6 +336,7 @@ void GlobalsInitPreConfig(void) SupportFastPatternForSigMatchTypes(); SCThresholdConfGlobalInit(); SCProtoNameInit(); + FrameConfigInit(); } static void GlobalsDestroy(SCInstance *suri)