]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #4356: detection: update of fast pattern printing
authorYehor Velykozhon -X (yvelykoz - SOFTSERVE INC at Cisco) <yvelykoz@cisco.com>
Thu, 4 Jul 2024 09:27:34 +0000 (09:27 +0000)
committerOleksii Shumeiko -X (oshumeik - SOFTSERVE INC at Cisco) <oshumeik@cisco.com>
Thu, 4 Jul 2024 09:27:34 +0000 (09:27 +0000)
Merge in SNORT/snort3 from ~YVELYKOZ/snort3:fp_print_upd to master

Squashed commit of the following:

commit a1a3383f6a3b44f28bb9b7168e39c85700c8156e
Author: Yehor Velykozhon <yvelykoz@cisco.com>
Date:   Tue Jun 18 15:17:36 2024 +0300

    detection: make print of fast pattern as a trace module

commit 544f928401ef43c87368026bec5f9e5d392d9b9f
Author: Yehor Velykozhon <yvelykoz@cisco.com>
Date:   Tue Jun 18 15:19:04 2024 +0300

    detection: add opt_tree traces in release build

commit ec3b9dccd4cb721be8bcace7c699840680a8f193
Author: Yehor Velykozhon <yvelykoz@cisco.com>
Date:   Tue Jun 18 15:10:15 2024 +0300

    detection: print only fast_pattern part of pattern

src/detection/detect_trace.cc
src/detection/detect_trace.h
src/detection/detection_module.cc
src/detection/fp_config.h
src/detection/fp_create.cc
src/detection/pattern_match_data.h
src/ips_options/ips_content.cc
src/main/modules.cc

index 559d535affb953cdf8d69ee077af61e0cfb97580..1f606c8e704e0309ad1ad4c4b1a0d82afe65cefb 100644 (file)
@@ -89,8 +89,8 @@ void print_pattern(const PatternMatchData* pmd, Packet* p)
     get_pattern_info(pmd, hex, txt, opts);
 
     debug_logf(detection_trace, TRACE_RULE_EVAL, p,
-        "Fast pattern %s[%u] = '%s' |%s| %s\n",
-        pmd->sticky_buf,  pmd->pattern_size, txt.c_str(), hex.c_str(), opts.c_str());
+        "Fast pattern %s[%u] = %s %s %s\n",
+        pmd->sticky_buf,  pmd->fp_length, txt.c_str(), hex.c_str(), opts.c_str());
 }
 
 void dump_buffer(const uint8_t* buff, unsigned len, Packet* p)
index 63bd81054f4dd0031c2e324ede1e194aa47d178d..1e3817e087a4877e36367ad1b6052de13e63b7f7 100644 (file)
@@ -48,6 +48,7 @@ enum
     TRACE_OPTION_TREE,
     TRACE_TAG,
     TRACE_CONT,
+    TRACE_FP_INFO,
 };
 
 void clear_trace_cursor_info();
index fc8e303f0254a7090d1a4e325bb2cf81d3654c30..6d8afaf2b775873c017604f232c127b953ec30cc 100644 (file)
@@ -39,9 +39,9 @@ using namespace snort;
 
 THREAD_LOCAL const Trace* detection_trace = nullptr;
 
-#ifdef DEBUG_MSGS
 static const TraceOption detection_trace_options[] =
 {
+#ifdef DEBUG_MSGS
     { "detect_engine", TRACE_DETECTION_ENGINE,  "enable detection engine trace logging" },
     { "rule_eval",     TRACE_RULE_EVAL,         "enable rule evaluation trace logging" },
     { "buffer",        TRACE_BUFFER,            "enable buffer trace logging" },
@@ -51,9 +51,10 @@ static const TraceOption detection_trace_options[] =
     { "opt_tree",      TRACE_OPTION_TREE,       "enable tree option trace logging" },
     { "tag",           TRACE_TAG,               "enable tag trace logging" },
     { "cont",          TRACE_CONT,              "enable rule continuation trace logging" },
+#endif
+    { "fp_info",       TRACE_FP_INFO,           "enable fast pattern info logging" },
     { nullptr, 0, nullptr }
 };
-#endif
 
 
 static const Parameter extend_to_service[] =
@@ -145,11 +146,7 @@ void DetectionModule::set_trace(const Trace* trace) const
 
 const TraceOption* DetectionModule::get_trace_options() const
 {
-#ifndef DEBUG_MSGS
-    return nullptr;
-#else
     return detection_trace_options;
-#endif
 }
 
 bool DetectionModule::begin(const char* fqn, int idx, SnortConfig* sc)
index d5717dbe5feef6526fb8a02ef232bbcb9dbd257d..382e2db2c5e28bbd7e3d5fe914e12e1238160a3d 100644 (file)
@@ -88,12 +88,6 @@ public:
     int get_debug_print_rule_groups_uncompiled() const
     { return portlists_flags & PL_DEBUG_PRINT_RULEGROUPS_UNCOMPILED; }
 
-    void set_debug_print_fast_patterns(bool b)
-    { debug_print_fast_pattern = b; }
-
-    bool get_debug_print_fast_patterns() const
-    { return debug_print_fast_pattern; }
-
     void set_split_any_any(bool enable)
     { split_any_any = enable; }
 
index 46d81eb285cd537cc911b623bf305e2751acda3f..22c69bc156ace1e433f53d2343f46aec4bd499cc 100644 (file)
@@ -127,7 +127,7 @@ static int finalize_detection_option_tree(SnortConfig* sc, detection_option_tree
             fixup_tree(root->children[i], true, 0);
         }
 
-        debug_logf(detection_trace, TRACE_OPTION_TREE, nullptr, "%3d %3d  %p %4s\n",
+        trace_logf(detection_trace, TRACE_OPTION_TREE, nullptr, "%3d %3d  %p %4s\n",
             0, root->num_children, (void*)root, "root");
 
         print_option_tree(root->children[i], 0);
@@ -231,7 +231,7 @@ static int otn_create_tree(OptTreeNode* otn, void** existing_tree, Mpse::MpseTyp
         {
             bool found_child_match = child->option_data == option_data;
 
-            for (i = 1; !found_child_match && i < bud->num_children; i++)
+            for (i = 1; !found_child_match and i < bud->num_children; i++)
             {
                 child = bud->children[i];
                 if (child->option_data == option_data)
@@ -410,6 +410,14 @@ static int fpFinishRuleGroupRule(
     {
         pattern = pmd->pattern_buf;
         pattern_length = pmd->pattern_size;
+
+        // alt buffer's pmd isn't guaranteed to be filled fully,
+        // so on first pass, setting fp_length to correct value
+        if (pmd->fp_length == 0)
+        {
+            pmd->fp_length = pmd->pattern_size;
+            pmd->fp_offset = 0;
+        }
     }
 
     if (pmd->pattern_size > otn->longestPatternLen)
@@ -436,12 +444,12 @@ static int fpFinishRuleGroup(SnortConfig* sc, RuleGroup* pg)
     {
         for ( auto& it : pg->pm_list[sect] )
         {
-            if ( it->group.normal_mpse && !it->group.normal_is_dup)
+            if ( it->group.normal_mpse and !it->group.normal_is_dup)
             {
                 queue_mpse(it->group.normal_mpse);
                 has_rules = true;
             }
-            if ( it->group.offload_mpse && !it->group.offload_is_dup)
+            if ( it->group.offload_mpse and !it->group.offload_is_dup)
             {
                 queue_mpse(it->group.offload_mpse);
                 has_rules = true;
@@ -476,7 +484,7 @@ static int fpFinishRuleGroup(SnortConfig* sc, RuleGroup* pg)
 
 static bool srvc_supports_section(const char* srvc)
 {
-    return (srvc && ( !strcmp("http", srvc) || !strcmp("http2",srvc) || !strcmp("http3",srvc)));
+    return (srvc and ( !strcmp("http", srvc) or !strcmp("http2",srvc) or !strcmp("http3",srvc)));
 }
 
 static int fpAddRuleGroupRule(
@@ -572,7 +580,7 @@ static int fpAddRuleGroupRule(
                 {
                     PatternMatcher* pm = pg->get_pattern_matcher(pmt, s, (PduSection)sect);
                     MpseGroup* mpg = &pm->group;
-                    const bool update_mpse = srvc || is_first_sect;
+                    const bool update_mpse = srvc or is_first_sect;
 
                     if ( !mpg->normal_mpse )
                     {
@@ -602,7 +610,7 @@ static int fpAddRuleGroupRule(
                         }
                     }
 
-                    if ( add_to_offload && !mpg->offload_mpse )
+                    if ( add_to_offload and !mpg->offload_mpse )
                     {
                         // Keep the created mpse alongside the same pm type as the main pmd
                         if (!update_mpse)
@@ -631,7 +639,7 @@ static int fpAddRuleGroupRule(
                         }
                     }
 
-                    if ( mpg->normal_mpse && update_mpse )
+                    if ( mpg->normal_mpse and update_mpse )
                     {
                         add_rule = true;
                         if ( main_pmd->is_negated() )
@@ -651,7 +659,7 @@ static int fpAddRuleGroupRule(
 
                             main_pmd->sticky_buf = pm->name;
 
-                            if ( fp->get_debug_print_fast_patterns() and !otn->soid )
+                            if ( !otn->soid )
                                 print_fp_info(s_group, otn, main_pmd, sect);
 
                             // Add Alternative patterns
@@ -660,13 +668,13 @@ static int fpAddRuleGroupRule(
                                 fpFinishRuleGroupRule(mpg->normal_mpse, otn, alt_pmd, fp, false);
                                 alt_pmd->sticky_buf = pm->name;
 
-                                if ( fp->get_debug_print_fast_patterns() and !otn->soid )
+                                if ( !otn->soid )
                                     print_fp_info(s_group, otn, alt_pmd, sect);
                             }
                         }
                     }
 
-                    if ( ol_pmd and mpg->offload_mpse && update_mpse )
+                    if ( ol_pmd and mpg->offload_mpse and update_mpse )
                     {
                         add_rule = true;
                         if ( ol_pmd->is_negated() )
@@ -686,7 +694,7 @@ static int fpAddRuleGroupRule(
 
                             main_pmd->sticky_buf = pm->name;
 
-                            if ( fp->get_debug_print_fast_patterns() and !otn->soid )
+                            if ( !otn->soid )
                                 print_fp_info(s_group, otn, main_pmd, sect);
 
                             // Add Alternative patterns
@@ -695,7 +703,7 @@ static int fpAddRuleGroupRule(
                                 fpFinishRuleGroupRule(mpg->offload_mpse, otn, alt_pmd, fp, false);
                                 alt_pmd->sticky_buf = pm->name;
 
-                                if ( fp->get_debug_print_fast_patterns() and !otn->soid )
+                                if ( !otn->soid )
                                     print_fp_info(s_group, otn, alt_pmd, sect);
                             }
                         }
@@ -943,10 +951,12 @@ static int fpGetFinalPattern(
     {
         ret_pattern = pattern;
         ret_bytes = bytes;
+        pmd->fp_length = pmd->pattern_size;
+
         return 0;
     }
 
-    if ( pmd->is_fast_pattern() && (pmd->fp_offset || pmd->fp_length) )
+    if ( pmd->is_fast_pattern() and (pmd->fp_offset or pmd->fp_length) )
     {
         /* (offset + length) potentially being larger than the pattern itself
          * is taken care of during parsing */
@@ -958,7 +968,7 @@ static int fpGetFinalPattern(
     ret_pattern = pattern;
     ret_bytes = fp->set_max(bytes);
 
-    if ( ret_bytes < pmd->pattern_size )
+    if ( ret_bytes < pmd->pattern_size or !pmd->fp_length )
         pmd->fp_length = ret_bytes;
 
     return 0;
@@ -1331,7 +1341,7 @@ static void fpPrintServiceRuleMapTable(GHash* p, const char* dir)
 {
     GHashNode* n;
 
-    if ( !p || !p->get_count() )
+    if ( !p or !p->get_count() )
         return;
 
     std::string label = "service rule counts - ";
@@ -1668,13 +1678,17 @@ static void print_nfp_info(const char* group, OptTreeNode* otn)
 void get_pattern_info(const PatternMatchData* pmd, string& hex, string& txt, string& opts)
 {
     char buf[8];
-
-    for ( unsigned i = 0; i < pmd->pattern_size; ++i )
+    hex = "| ";
+    txt = "'";
+    for ( unsigned i = pmd->fp_offset; i < pmd->fp_offset + pmd->fp_length; ++i )
     {
         snprintf(buf, sizeof(buf), "%2.02X ", (uint8_t)pmd->pattern_buf[i]);
         hex += buf;
         txt += isprint(pmd->pattern_buf[i]) ? pmd->pattern_buf[i] : '.';
     }
+    hex += "|";
+    txt += "'";
+
     opts = "(";
     if ( pmd->is_fast_pattern() )
         opts += " user";
@@ -1683,13 +1697,14 @@ void get_pattern_info(const PatternMatchData* pmd, string& hex, string& txt, str
     opts += " )";
 }
 
-static void print_fp_info(const char* group, const OptTreeNode* otn, const PatternMatchData* pmd, int sect)
+static void print_fp_info(
+    const char* group, const OptTreeNode* otn, const PatternMatchData* pmd, int sect)
 {
     std::string hex, txt, opts;
 
     get_pattern_info(pmd, hex, txt, opts);
-    LogMessage("FP %s %u:%u:%u %s[%d] = '%s' |%s| %s, section %s\n",
-        group, otn->sigInfo.gid, otn->sigInfo.sid, otn->sigInfo.rev,
-        pmd->sticky_buf, pmd->pattern_size, txt.c_str(), hex.c_str(), opts.c_str(), section_to_str[sect]);
-}
 
+    trace_logf(detection_trace, TRACE_FP_INFO, nullptr, "%s group, %u:%u:%u %s[%u] = %s %s %s, section %s\n",
+        group, otn->sigInfo.gid, otn->sigInfo.sid, otn->sigInfo.rev, pmd->sticky_buf, pmd->fp_length,
+        txt.c_str(), hex.c_str(), opts.c_str(), section_to_str[sect]);
+}
index e676fad2d6b0d9837f2d5e30887efecec2b51bf4..3d9629f0ca6cd653a8c018137412540c0d665e9d 100644 (file)
@@ -73,8 +73,8 @@ struct PatternMatchData
     uint16_t flags = 0;          // from above enum
     uint16_t mpse_flags;     // passed through to mpse
 
-    uint16_t fp_offset;
-    uint16_t fp_length;
+    uint16_t fp_offset = 0;
+    uint16_t fp_length = 0;
 
     bool is_unbounded() const
     { return !depth; }
index e394bb10df3e53c0f5562ddfed6a13209c32f835..48730f57a0d26ffb9e8527cc90a69e54f792ef39 100644 (file)
@@ -731,6 +731,16 @@ bool ContentModule::end(const char*, int, SnortConfig*)
 
     if ( cd->pmd.is_negated() )
     {
+        if (cd->pmd.fp_length || cd->pmd.fp_offset)
+        {
+            ParseWarning(WARN_RULES,
+                "Fast pattern constraints for negated "
+                "content will be ignored");
+
+            cd->pmd.fp_length = cd->pmd.pattern_size;
+            cd->pmd.fp_offset = 0;
+        }
+
         cd->pmd.last_check = (PmdLastCheck*)snort_calloc(
             ThreadConfig::get_instance_max(), sizeof(*cd->pmd.last_check));
     }
index 448a5b9840008f958b041a7186d3272bb9ecc692..9c48acdcf4dfd9a851eaa6be2012f516223bfc92 100644 (file)
@@ -198,9 +198,6 @@ static const Parameter search_engine_params[] =
     { "rule_db_dir", Parameter::PT_STRING, nullptr, nullptr,
       "deserialize rule databases from given directory" },
 
-    { "show_fast_patterns", Parameter::PT_BOOL, nullptr, "false",
-      "print fast pattern info for each rule" },
-
     { "split_any_any", Parameter::PT_BOOL, nullptr, "true",
       "evaluate any-any rules separately to save memory" },
 
@@ -310,8 +307,6 @@ bool SearchEngineModule::set(const char*, Value& v, SnortConfig* sc)
         if ( !fp->set_offload_search_method(v.get_string()) )
             return false;
     }
-    else if ( v.is("show_fast_patterns") )
-        fp->set_debug_print_fast_patterns(v.get_bool());
 
     else if ( v.is("split_any_any") )
         fp->set_split_any_any(v.get_bool());