From 072edee259cebbff312fa8f8ad04d896bf73e562 Mon Sep 17 00:00:00 2001 From: "Steve Chew (stechew)" Date: Fri, 28 Feb 2020 03:58:34 +0000 Subject: [PATCH] Merge pull request #1949 in SNORT/snort3 from ~OSERHIIE/snort3:trace_bitmask to master Squashed commit of the following: commit 4cccd12b0aacbc85543aabc63db1ad5212bc4a7d Author: Oleksandr Serhiienko Date: Wed Feb 12 19:31:05 2020 +0200 detection: refactoring updates to detection. Moved DetectionModule into a separate file. commit cded4b12458ea9d4c7456ebd93041482a91c2a30 Author: Serhii Vlasiuk Date: Tue Feb 4 20:34:00 2020 +0200 framework: add generic convertation trace string to bitmaks. commit 29c144ae2e148b35d76bebef24146d84adc83311 Author: Oleksandr Serhiienko Date: Thu Jan 16 17:08:49 2020 +0200 detection: added support for trace config option to take a list of strings with verbosity level instead of bitmask --- src/detection/CMakeLists.txt | 2 + src/detection/context_switcher.cc | 2 +- src/detection/detect_trace.cc | 1 - src/detection/detect_trace.h | 1 + src/detection/detection_engine.cc | 2 +- src/detection/detection_module.cc | 222 +++++++++++++++++++++++++ src/detection/detection_module.h | 50 ++++++ src/detection/detection_options.cc | 2 +- src/detection/fp_detect.cc | 2 +- src/framework/module.cc | 76 +++++++-- src/framework/module.h | 27 ++- src/framework/value.h | 2 +- src/main/modules.cc | 254 +++++++++++------------------ src/main/modules.h | 3 - 14 files changed, 459 insertions(+), 187 deletions(-) create mode 100644 src/detection/detection_module.cc create mode 100644 src/detection/detection_module.h diff --git a/src/detection/CMakeLists.txt b/src/detection/CMakeLists.txt index a6d88da14..064c53e32 100644 --- a/src/detection/CMakeLists.txt +++ b/src/detection/CMakeLists.txt @@ -21,6 +21,8 @@ add_library (detection OBJECT context_switcher.h detect.cc detection_engine.cc + detection_module.cc + detection_module.h detection_options.cc detection_options.h detection_util.cc diff --git a/src/detection/context_switcher.cc b/src/detection/context_switcher.cc index 9faeb3cb9..7debfdbf6 100644 --- a/src/detection/context_switcher.cc +++ b/src/detection/context_switcher.cc @@ -26,11 +26,11 @@ #include -#include "main/modules.h" #include "main/snort_debug.h" #include "packet_io/active.h" #include "utils/stats.h" +#include "detection_module.h" #include "detect_trace.h" #include "ips_context.h" #include "ips_context_data.h" diff --git a/src/detection/detect_trace.cc b/src/detection/detect_trace.cc index 5a2b7aab3..047b58de5 100644 --- a/src/detection/detect_trace.cc +++ b/src/detection/detect_trace.cc @@ -168,4 +168,3 @@ void node_eval_trace(const detection_option_tree_node_t*, const Cursor&, Packet* } #endif - diff --git a/src/detection/detect_trace.h b/src/detection/detect_trace.h index 21c315f93..43189147e 100644 --- a/src/detection/detect_trace.h +++ b/src/detection/detect_trace.h @@ -36,6 +36,7 @@ struct PatternMatchData; enum { + TRACE_NONE = 0, TRACE_DETECTION_ENGINE = 0x1, TRACE_RULE_EVAL = 0x2, TRACE_BUFFER_MINIMAL = 0x4, diff --git a/src/detection/detection_engine.cc b/src/detection/detection_engine.cc index cb688e7fc..db34ca33a 100644 --- a/src/detection/detection_engine.cc +++ b/src/detection/detection_engine.cc @@ -30,7 +30,6 @@ #include "helpers/ring.h" #include "latency/packet_latency.h" #include "main/analyzer.h" -#include "main/modules.h" #include "main/snort_config.h" #include "main/snort_debug.h" #include "main/thread.h" @@ -44,6 +43,7 @@ #include "utils/stats.h" #include "context_switcher.h" +#include "detection_module.h" #include "detection_util.h" #include "detect.h" #include "detect_trace.h" diff --git a/src/detection/detection_module.cc b/src/detection/detection_module.cc new file mode 100644 index 000000000..639880a2e --- /dev/null +++ b/src/detection/detection_module.cc @@ -0,0 +1,222 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License Version 2 as published +// by the Free Software Foundation. You may not use, modify or distribute +// this program under any other version of the GNU General Public License. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +//-------------------------------------------------------------------------- + +// detection_module.cc author Oleksandr Serhiienko +// based on work by Russ Combs + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "detection_module.h" + +#include + +#include "log/messages.h" +#include "main/snort_config.h" +#include "main/thread_config.h" + +#include "detect_trace.h" + +using namespace snort; + +/* *INDENT-OFF* */ // Uncrustify handles this section incorrectly. +static const Parameter detection_module_trace_values[] = +{ + { "detect_engine", Parameter::PT_INT, "0:max53", "0", "enable detection engine trace logging" }, + + { "rule_eval", Parameter::PT_INT, "0:max53", "0", "enable rule evaluation trace logging" }, + + { "buf_min", Parameter::PT_INT, "0:max53", "0", "enable min buffer trace logging" }, + + { "buf_verbose", Parameter::PT_INT, "0:max53", "0", "enable verbose buffer trace logging" }, + + { "rule_vars", Parameter::PT_INT, "0:max53", "0", "enable rule variables trace logging" }, + + { "fp_search", Parameter::PT_INT, "0:max53", "0", "enable fast pattern search trace logging" }, + + { "pkt_detect", Parameter::PT_INT, "0:max53", "0", "enable packet detection trace logging" }, + + { "opt_tree", Parameter::PT_INT, "0:max53", "0", "enable tree option trace logging" }, + + { "tag", Parameter::PT_INT, "0:max53", "0", "enable tag trace logging" }, + + { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } +}; + +static const Parameter detection_module_trace[] = +{ + { "trace", Parameter::PT_TABLE, detection_module_trace_values, nullptr, "trace config for detection module" }, + + { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } +}; + +static const TraceValue detection_trace_masks[] = +{ + { "detect_engine", TRACE_DETECTION_ENGINE }, + { "rule_eval", TRACE_RULE_EVAL }, + { "buf_min", TRACE_BUFFER_MINIMAL }, + { "buf_verbose", TRACE_BUFFER_VERBOSE }, + { "rule_vars", TRACE_RULE_VARS }, + { "fp_search", TRACE_FP_SEARCH }, + { "pkt_detect", TRACE_PKT_DETECTION }, + { "opt_tree", TRACE_OPTION_TREE }, + { "tag", TRACE_TAG } +}; + +static TraceMask detection_module_trace_mask(detection_trace_masks, + (sizeof(detection_trace_masks) / sizeof(TraceValue))); + +static const Parameter detection_params[] = +{ + { "asn1", Parameter::PT_INT, "0:65535", "0", + "maximum decode nodes" }, + + { "global_default_rule_state", Parameter::PT_BOOL, nullptr, "true", + "enable or disable rules by default (overridden by ips policy settings)" }, + + { "global_rule_state", Parameter::PT_BOOL, nullptr, "false", + "apply rule_state against all policies" }, + +#ifdef HAVE_HYPERSCAN + { "hyperscan_literals", Parameter::PT_BOOL, nullptr, "false", + "use hyperscan for content literal searches instead of boyer-moore" }, +#endif + + { "offload_limit", Parameter::PT_INT, "0:max32", "99999", + "minimum sizeof PDU to offload fast pattern search (defaults to disabled)" }, + + { "offload_threads", Parameter::PT_INT, "0:max32", "0", + "maximum number of simultaneous offloads (defaults to disabled)" }, + + { "pcre_enable", Parameter::PT_BOOL, nullptr, "true", + "enable pcre pattern matching" }, + + { "pcre_match_limit", Parameter::PT_INT, "0:max32", "1500", + "limit pcre backtracking, 0 = off" }, + + { "pcre_match_limit_recursion", Parameter::PT_INT, "0:max32", "1500", + "limit pcre stack consumption, 0 = off" }, + + { "pcre_override", Parameter::PT_BOOL, nullptr, "true", + "enable pcre match limit overrides when pattern matching (ie ignore /O)" }, + +#ifdef HAVE_HYPERSCAN + { "pcre_to_regex", Parameter::PT_BOOL, nullptr, "false", + "enable the use of regex instead of pcre for compatible expressions" }, +#endif + + { "enable_address_anomaly_checks", Parameter::PT_BOOL, nullptr, "false", + "enable check and alerting of address anomalies" }, + + { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } +}; +/* *INDENT-ON* */ + +#define detection_help \ + "configure general IPS rule processing parameters" + +DetectionModule::DetectionModule() : Module("detection", detection_help, + detection_params, false, &TRACE_NAME(detection), detection_module_trace, &detection_module_trace_mask) +{ } + +bool DetectionModule::end(const char*, int, SnortConfig* sc) +{ + if ( sc->offload_threads and ThreadConfig::get_instance_max() != 1 ) + ParseError("You can not enable experimental offload with more than one packet thread."); + + return true; +} + +bool DetectionModule::set(const char* fqn, Value& v, SnortConfig* sc) +{ + if ( v.is("asn1") ) + sc->asn1_mem = v.get_uint16(); + + else if ( v.is("global_default_rule_state") ) + sc->global_default_rule_state = v.get_bool(); + + else if ( v.is("global_rule_state") ) + sc->global_rule_state = v.get_bool(); + +#ifdef HAVE_HYPERSCAN + else if ( v.is("hyperscan_literals") ) + sc->hyperscan_literals = v.get_bool(); +#endif + + else if ( v.is("offload_limit") ) + sc->offload_limit = v.get_uint32(); + + else if ( v.is("offload_threads") ) + sc->offload_threads = v.get_uint32(); + + else if ( v.is("pcre_enable") ) + v.update_mask(sc->run_flags, RUN_FLAG__NO_PCRE, true); + + else if ( v.is("pcre_match_limit") ) + sc->pcre_match_limit = v.get_uint32(); + + else if ( v.is("pcre_match_limit_recursion") ) + { + // Cap the pcre recursion limit to not exceed the stack size. + // + // Note that even if we tried to call setrlimit() here, the threads + // will still get the stack size decided upon the start of snort3, + // which is 2M (for x86_64!) if snort3 started with unlimited + // stack size (ulimit -s). See the pthread_create() man page, or glibc + // source code. + + // Determine the current stack size limit: + rlimit lim; + getrlimit(RLIMIT_STACK, &lim); + rlim_t thread_stack_size = lim.rlim_cur; + + const size_t fudge_factor = 1 << 19; // 1/2 M + const size_t pcre_stack_frame_size = 1024; // pcretest -m -C + + if (lim.rlim_cur == RLIM_INFINITY) + thread_stack_size = 1 << 21; // 2M + + long int max_rec = (thread_stack_size - fudge_factor) / pcre_stack_frame_size; + if (max_rec < 0) + max_rec = 0; + + sc->pcre_match_limit_recursion = v.get_uint32(); + if (sc->pcre_match_limit_recursion > max_rec) + { + sc->pcre_match_limit_recursion = max_rec; + LogMessage("Capping pcre_match_limit_recursion to %ld, thread stack_size %ld.\n", + sc->pcre_match_limit_recursion, thread_stack_size); + } + } + + else if ( v.is("pcre_override") ) + sc->pcre_override = v.get_bool(); + +#ifdef HAVE_HYPERSCAN + else if ( v.is("pcre_to_regex") ) + sc->pcre_to_regex = v.get_bool(); +#endif + + else if ( v.is("enable_address_anomaly_checks") ) + sc->address_anomaly_check_enabled = v.get_bool(); + else + return Module::set(fqn, v, sc); + + return true; +} diff --git a/src/detection/detection_module.h b/src/detection/detection_module.h new file mode 100644 index 000000000..547a84fff --- /dev/null +++ b/src/detection/detection_module.h @@ -0,0 +1,50 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License Version 2 as published +// by the Free Software Foundation. You may not use, modify or distribute +// this program under any other version of the GNU General Public License. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +//-------------------------------------------------------------------------- + +// detection_module.h author Oleksandr Serhiienko +// based on work by Russ Combs + +#ifndef DETECTION_MODULE_H +#define DETECTION_MODULE_H + +#include "framework/module.h" + +namespace snort +{ +class DetectionModule : public Module +{ +public: + DetectionModule(); + + bool set(const char*, Value&, SnortConfig*) override; + bool end(const char*, int, SnortConfig*) override; + + const PegInfo* get_pegs() const override + { return pc_names; } + + PegCount* get_counts() const override + { return (PegCount*) &pc; } + + Usage get_usage() const override + { return GLOBAL; } +}; +} + +extern Trace TRACE_NAME(detection); + +#endif // DETECTION_MODULE_H diff --git a/src/detection/detection_options.cc b/src/detection/detection_options.cc index 6fd3b26a2..884ebe2ab 100644 --- a/src/detection/detection_options.cc +++ b/src/detection/detection_options.cc @@ -45,7 +45,6 @@ #include "latency/packet_latency.h" #include "latency/rule_latency_state.h" #include "log/messages.h" -#include "main/modules.h" #include "main/snort_config.h" #include "main/snort_debug.h" #include "main/thread_config.h" @@ -56,6 +55,7 @@ #include "utils/util.h" #include "detection_engine.h" +#include "detection_module.h" #include "detection_util.h" #include "detect_trace.h" #include "fp_create.h" diff --git a/src/detection/fp_detect.cc b/src/detection/fp_detect.cc index 7ec4725c8..f7c9dbcb8 100644 --- a/src/detection/fp_detect.cc +++ b/src/detection/fp_detect.cc @@ -47,7 +47,6 @@ #include "latency/packet_latency.h" #include "latency/rule_latency.h" #include "log/messages.h" -#include "main/modules.h" #include "main/snort.h" #include "main/snort_config.h" #include "main/snort_debug.h" @@ -69,6 +68,7 @@ #include "detect_trace.h" #include "detection_util.h" #include "detection_engine.h" +#include "detection_module.h" #include "detection_options.h" #include "fp_config.h" #include "fp_create.h" diff --git a/src/framework/module.cc b/src/framework/module.cc index 53b989a81..5015cdfa1 100644 --- a/src/framework/module.cc +++ b/src/framework/module.cc @@ -25,14 +25,28 @@ using namespace snort; -static const Parameter defaults[] = +static const Parameter default_trace[] = { - { "trace", Parameter::PT_INT, "0:max53", nullptr, - "mask for enabling debug traces in module" }, + { "all", Parameter::PT_INT, "0:max32", "0", "enabling traces in module" }, { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } }; +static const Parameter default_trace_params[] = +{ + { "trace", Parameter::PT_TABLE, default_trace, nullptr, "trace config" }, + + { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } +}; + +static const TraceValue default_trace_values[] = +{ + { "all", 1 } +}; + +static TraceMask s_default_trace_values(default_trace_values, + (sizeof(default_trace_values) / sizeof(TraceValue))); + std::string Command::get_arg_list() const { std::string args = "("; @@ -49,11 +63,31 @@ std::string Command::get_arg_list() const return args; } +bool TraceMask::set(const Value& v, Trace* mask) +{ + const TraceValue* tv = &values[0]; + int isize = m_size; + + while ( isize-- ) + { + if ( v.is(tv->alias) ) + { + uint8_t opt_val = v.get_uint8(); + if ( opt_val ) + *mask |= tv->mask; + return true; + } + tv++; + } + + return false; +} + void Module::init(const char* s, const char* h) { name = s; help = h; - params = &defaults[(sizeof(defaults) / sizeof(Parameter)) - 1]; + params = &default_trace_params[(sizeof(default_trace_params) / sizeof(Parameter)) - 1]; default_params = params; list = false; num_counts = -1; @@ -62,7 +96,8 @@ void Module::init(const char* s, const char* h) Module::Module(const char* s, const char* h) { init(s, h); } -Module::Module(const char* s, const char* h, const Parameter* p, bool is_list, Trace* t) +Module::Module(const char* s, const char* h, const Parameter* p, bool is_list, Trace* t, + const Parameter* module_trace_param, TraceMask* module_trace_mask) { init(s, h); list = is_list; @@ -71,19 +106,26 @@ Module::Module(const char* s, const char* h, const Parameter* p, bool is_list, T // FIXIT-L: This will not be valid after adding more default options if ( t ) - default_params = defaults; + { + if ( module_trace_param ) + { + default_params = module_trace_param; + trace_mask = module_trace_mask; + } + else + { + default_params = default_trace_params; + trace_mask = &s_default_trace_values; + } + } } -bool Module::set(const char*, Value& v, SnortConfig*) +bool Module::set(const char* fqn, Value& v, SnortConfig*) { - if ( v.is("trace") ) - { - if ( trace ) - *trace = v.get_uint64(); - } - else - return false; - return true; + if ( strstr(fqn, ".trace.") ) + return trace_mask and trace_mask->set(v, trace); + + return false; } void Module::sum_stats(bool accumulate_now_stats) @@ -198,8 +240,8 @@ bool Module::verified_end(const char* fqn, int idx, SnortConfig* c) void Module::enable_trace() { - if ( trace ) - *trace = 1; + if ( trace_mask ) + trace_mask->set(trace); } namespace snort diff --git a/src/framework/module.h b/src/framework/module.h index f68ae8b0c..dbfc76442 100644 --- a/src/framework/module.h +++ b/src/framework/module.h @@ -75,6 +75,30 @@ struct RuleMap const char* msg; }; +struct TraceValue { + const char* alias; + Trace mask; +}; + +class TraceMask +{ +public: + TraceMask(const TraceValue* array, size_t size) : values(array), m_size(size) + {} + + bool set(const Value& v, Trace* mask); + + bool set(Trace* mask) + { + *mask = 1; + return true; + } + +private: + const TraceValue* values; + size_t m_size; +}; + class SO_PUBLIC Module { public: @@ -192,7 +216,7 @@ public: protected: Module(const char* name, const char* help); Module(const char* name, const char* help, const Parameter*, - bool is_list = false, Trace* = nullptr); + bool is_list = false, Trace* = nullptr, const Parameter* = nullptr, TraceMask* = nullptr); private: friend ModuleManager; @@ -206,6 +230,7 @@ private: const Parameter* params; const Parameter* default_params = nullptr; + TraceMask* trace_mask = nullptr; bool list; int table_level = 0; diff --git a/src/framework/value.h b/src/framework/value.h index a9f887179..b8190bd9d 100644 --- a/src/framework/value.h +++ b/src/framework/value.h @@ -86,7 +86,7 @@ public: const char* get_name() const { return param ? param->name : nullptr; } - bool is(const char* s) + bool is(const char* s) const { return param ? !strcmp(param->name, s) : false; } bool get_bool() const diff --git a/src/main/modules.cc b/src/main/modules.cc index ade160e8e..cbb683d84 100644 --- a/src/main/modules.cc +++ b/src/main/modules.cc @@ -27,6 +27,7 @@ #include #include "codecs/codec_module.h" +#include "detection/detection_module.h" #include "detection/fp_config.h" #include "detection/rules.h" #include "filters/detection_filter.h" @@ -65,166 +66,6 @@ using namespace snort; using namespace std; -//------------------------------------------------------------------------- -// detection module -//------------------------------------------------------------------------- - -/* *INDENT-OFF* */ // Uncrustify handles this section incorrectly. -static const Parameter detection_params[] = -{ - { "asn1", Parameter::PT_INT, "0:65535", "0", - "maximum decode nodes" }, - - { "global_default_rule_state", Parameter::PT_BOOL, nullptr, "true", - "enable or disable rules by default (overridden by ips policy settings)" }, - - { "global_rule_state", Parameter::PT_BOOL, nullptr, "false", - "apply rule_state against all policies" }, - -#ifdef HAVE_HYPERSCAN - { "hyperscan_literals", Parameter::PT_BOOL, nullptr, "false", - "use hyperscan for content literal searches instead of boyer-moore" }, -#endif - - { "offload_limit", Parameter::PT_INT, "0:max32", "99999", - "minimum sizeof PDU to offload fast pattern search (defaults to disabled)" }, - - { "offload_threads", Parameter::PT_INT, "0:max32", "0", - "maximum number of simultaneous offloads (defaults to disabled)" }, - - { "pcre_enable", Parameter::PT_BOOL, nullptr, "true", - "enable pcre pattern matching" }, - - { "pcre_match_limit", Parameter::PT_INT, "0:max32", "1500", - "limit pcre backtracking, 0 = off" }, - - { "pcre_match_limit_recursion", Parameter::PT_INT, "0:max32", "1500", - "limit pcre stack consumption, 0 = off" }, - - { "pcre_override", Parameter::PT_BOOL, nullptr, "true", - "enable pcre match limit overrides when pattern matching (ie ignore /O)" }, - -#ifdef HAVE_HYPERSCAN - { "pcre_to_regex", Parameter::PT_BOOL, nullptr, "false", - "enable the use of regex instead of pcre for compatible expressions" }, -#endif - - { "enable_address_anomaly_checks", Parameter::PT_BOOL, nullptr, "false", - "enable check and alerting of address anomalies" }, - - { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } -}; -/* *INDENT-ON* */ - -#define detection_help \ - "configure general IPS rule processing parameters" - -class DetectionModule : public Module -{ -public: - DetectionModule() : - Module("detection", detection_help, detection_params, false, &TRACE_NAME(detection)) {} - - bool set(const char*, Value&, SnortConfig*) override; - bool end(const char*, int, SnortConfig*) override; - - const PegInfo* get_pegs() const override - { return pc_names; } - - PegCount* get_counts() const override - { return (PegCount*) &pc; } - - Usage get_usage() const override - { return GLOBAL; } -}; - -bool DetectionModule::end(const char*, int, SnortConfig* sc) -{ - if ( sc->offload_threads and ThreadConfig::get_instance_max() != 1 ) - ParseError("You can not enable experimental offload with more than one packet thread."); - - return true; -} - -bool DetectionModule::set(const char* fqn, Value& v, SnortConfig* sc) -{ - if ( v.is("asn1") ) - sc->asn1_mem = v.get_uint16(); - - else if ( v.is("global_default_rule_state") ) - sc->global_default_rule_state = v.get_bool(); - - else if ( v.is("global_rule_state") ) - sc->global_rule_state = v.get_bool(); - -#ifdef HAVE_HYPERSCAN - else if ( v.is("hyperscan_literals") ) - sc->hyperscan_literals = v.get_bool(); -#endif - - else if ( v.is("offload_limit") ) - sc->offload_limit = v.get_uint32(); - - else if ( v.is("offload_threads") ) - sc->offload_threads = v.get_uint32(); - - else if ( v.is("pcre_enable") ) - v.update_mask(sc->run_flags, RUN_FLAG__NO_PCRE, true); - - else if ( v.is("pcre_match_limit") ) - sc->pcre_match_limit = v.get_uint32(); - - else if ( v.is("pcre_match_limit_recursion") ) - { - // Cap the pcre recursion limit to not exceed the stack size. - // - // Note that even if we tried to call setrlimit() here, the threads - // will still get the stack size decided upon the start of snort3, - // which is 2M (for x86_64!) if snort3 started with unlimited - // stack size (ulimit -s). See the pthread_create() man page, or glibc - // source code. - - // Determine the current stack size limit: - rlimit lim; - getrlimit(RLIMIT_STACK, &lim); - rlim_t thread_stack_size = lim.rlim_cur; - - const size_t fudge_factor = 1 << 19; // 1/2 M - const size_t pcre_stack_frame_size = 1024; // pcretest -m -C - - if (lim.rlim_cur == RLIM_INFINITY) - thread_stack_size = 1 << 21; // 2M - - long int max_rec = (thread_stack_size - fudge_factor) / pcre_stack_frame_size; - if (max_rec < 0) - max_rec = 0; - - sc->pcre_match_limit_recursion = v.get_uint32(); - if (sc->pcre_match_limit_recursion > max_rec) - { - sc->pcre_match_limit_recursion = max_rec; - LogMessage("Capping pcre_match_limit_recursion to %ld, thread stack_size %ld.\n", - sc->pcre_match_limit_recursion, thread_stack_size); - } - } - - else if ( v.is("pcre_override") ) - sc->pcre_override = v.get_bool(); - -#ifdef HAVE_HYPERSCAN - else if ( v.is("pcre_to_regex") ) - sc->pcre_to_regex = v.get_bool(); -#endif - - else if ( v.is("enable_address_anomaly_checks") ) - sc->address_anomaly_check_enabled = v.get_bool(); - - else - return Module::set(fqn, v, sc); - - return true; -} - //------------------------------------------------------------------------- // event queue module //------------------------------------------------------------------------- @@ -2144,3 +1985,96 @@ void module_init() ModuleManager::add_module(new HostTrackerModule); ModuleManager::add_module(new HostCacheModule); } + +#ifdef UNIT_TEST + +#include + +//------------------------------------------------------------------------- +// Set trace option tests +//------------------------------------------------------------------------- + +namespace +{ +const TraceValue default_trace_values[] = +{ + { "all", 1 } +}; + +TraceMask s_default_trace_values(default_trace_values, + (sizeof(default_trace_values) / sizeof(TraceValue))); +} + +TEST_CASE("TraceMask - single trace value", "[trace_mask]") +{ + Trace test_bitmask = 0; + Parameter p("all", Parameter::PT_INT, "0:max32", "0", "enabling traces in module"); + Value trace_val((double)1); + trace_val.set(&p); + + bool result = s_default_trace_values.set(trace_val, &test_bitmask); + CHECK( result == true ); + CHECK( test_bitmask == 1 ); +} + +TEST_CASE("TraceMask - multiple trace values", "[trace_mask]") +{ + enum + { + TEST_TRACE_DETECTION_ENGINE = 0x1, + TEST_TRACE_RULE_VARS = 0x10, + TEST_TRACE_OPTION_TREE = 0x80, + TEST_TRACE_TAG = 0x100, + }; + const TraceValue test_trace_values[] = + { + { "detect_engine", TEST_TRACE_DETECTION_ENGINE }, + { "rule_vars", TEST_TRACE_RULE_VARS }, + { "opt_tree", TEST_TRACE_OPTION_TREE }, + { "tag", TEST_TRACE_TAG } + }; + TraceMask test_mask(test_trace_values, (sizeof(test_trace_values) / sizeof(TraceValue))); + + Trace test_bitmask = 0; + Parameter p1("detect_engine", Parameter::PT_INT, "0:max32", "0", "p1"); + Parameter p2("rule_vars", Parameter::PT_INT, "0:max32", "0", "p2"); + Parameter p3("opt_tree", Parameter::PT_INT, "0:max32", "0", "p3"); + Parameter p4("tag", Parameter::PT_INT, "0:max32", "0", "p4"); + Value trace_val("trace"); + trace_val.set(&p1); + trace_val.set_enum(1); + + bool result = test_mask.set(trace_val, &test_bitmask); + CHECK( result == true ); + CHECK( test_bitmask == TEST_TRACE_DETECTION_ENGINE ); + + trace_val.set(&p2); + result = test_mask.set(trace_val, &test_bitmask); + CHECK( result == true ); + CHECK( test_bitmask == (TEST_TRACE_DETECTION_ENGINE | TEST_TRACE_RULE_VARS) ); + + trace_val.set(&p3); + result = test_mask.set(trace_val, &test_bitmask); + CHECK( result == true ); + CHECK( test_bitmask == (TEST_TRACE_DETECTION_ENGINE | TEST_TRACE_RULE_VARS | TEST_TRACE_OPTION_TREE) ); + + trace_val.set(&p4); + result = test_mask.set(trace_val, &test_bitmask); + CHECK( result == true ); + CHECK( test_bitmask == (TEST_TRACE_DETECTION_ENGINE | TEST_TRACE_RULE_VARS | TEST_TRACE_OPTION_TREE | TEST_TRACE_TAG) ); +} + +TEST_CASE("TraceMask - incorrect trace value", "[trace_mask]") +{ + Trace test_bitmask = 0; + Parameter p("test", Parameter::PT_INT, "0:max32", "0", "p"); + Value trace_val("trace"); + trace_val.set(&p); + trace_val.set_enum(1); + + bool result = s_default_trace_values.set(trace_val, &test_bitmask); + CHECK( result == false ); + CHECK( test_bitmask == 0 ); +} + +#endif // UNIT_TEST diff --git a/src/main/modules.h b/src/main/modules.h index 99687469d..4f4f0e019 100644 --- a/src/main/modules.h +++ b/src/main/modules.h @@ -32,7 +32,4 @@ void module_init(); const char* get_lua_defaults(); -extern Trace TRACE_NAME(detection); // FIXIT-L refactor detection module out - #endif - -- 2.47.3