From b24c5c0e46790df02e37a14da1943b442d896f07 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Thu, 14 Nov 2024 16:30:11 -0800 Subject: [PATCH] Order rule traversal in RuleMatcher::Match() operations by Rule index This ordering fixes a test failure we're seeing on Alpine for the signatures/tcp-end-of-match btest, since discrepancies in rule match traversal could lead to discrepancies in corresponding event ordering. It looks safe to rely on across platforms since the index is driven by signature load order, which shouldn't deviate. If this somehow doesn't hold in the future, we'll only wind up with a test failure, not incorrect match behavior. (Correction to 2e03fbb8b01379126a57149d083d4c0f23b9188a, which I pushed accidentally.) --- src/Rule.h | 3 --- src/RuleMatcher.cc | 23 +++++++------------ .../signatures.tcp-end-of-match/.stdout | 4 ++-- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/Rule.h b/src/Rule.h index 4cc75b0a37..5481d3d57b 100644 --- a/src/Rule.h +++ b/src/Rule.h @@ -59,9 +59,6 @@ public: void PrintDebug(); - bool operator==(const Rule& other) { return strcmp(ID(), other.ID()) == 0; } - bool operator<(const Rule& other) { return strcmp(ID(), other.ID()) < 0; } - static const char* TypeToString(Rule::PatternType type); private: diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index dc96718900..ef3860748f 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -657,8 +657,7 @@ RuleMatcher::MIME_Matches* RuleMatcher::Match(RuleFileMagicState* state, const u } // Find rules for which patterns have matched. - auto cmp = [](Rule* a, Rule* b) { return *a < *b; }; - set rule_matches(cmp); + map rule_matches; for ( AcceptingMatchSet::const_iterator it = accepted_matches.begin(); it != accepted_matches.end(); ++it ) { auto [aidx, mpos] = *it; @@ -666,11 +665,11 @@ RuleMatcher::MIME_Matches* RuleMatcher::Match(RuleFileMagicState* state, const u Rule* r = Rule::rule_table[aidx - 1]; if ( AllRulePatternsMatched(r, mpos, accepted_matches) ) - rule_matches.insert(r); + rule_matches[r->Index()] = r; } - for ( set::const_iterator it = rule_matches.begin(); it != rule_matches.end(); ++it ) { - Rule* r = *it; + for ( const auto& entry : rule_matches ) { + Rule* r = entry.second; for ( const auto& action : r->actions ) { const RuleActionMIME* ram = dynamic_cast(action); @@ -842,12 +841,7 @@ void RuleMatcher::Match(RuleEndpointState* state, Rule::PatternType type, const // matched patterns per connection (which is a plausible assumption). // Find rules for which patterns have matched. - auto cmp = [](pair a, pair b) { - if ( *a.first == *b.first ) - return a.second < b.second; - return *a.first < *b.first; - }; - set, decltype(cmp)> rule_matches(cmp); + map> rule_matches; for ( AcceptingMatchSet::const_iterator it = accepted_matches.begin(); it != accepted_matches.end(); ++it ) { AcceptIdx aidx = it->first; @@ -856,13 +850,12 @@ void RuleMatcher::Match(RuleEndpointState* state, Rule::PatternType type, const Rule* r = Rule::rule_table[aidx - 1]; if ( AllRulePatternsMatched(r, mpos, accepted_matches) ) - rule_matches.insert(make_pair(r, mpos)); + rule_matches[r->Index()] = make_pair(r, mpos); } // Check which of the matching rules really belong to any of our nodes. - - for ( set>::const_iterator it = rule_matches.begin(); it != rule_matches.end(); ++it ) { - auto [r, match_end_pos] = *it; + for ( const auto& entry : rule_matches ) { + auto [r, match_end_pos] = entry.second; DBG_LOG(DBG_RULES, "Accepted rule: %s", r->id); diff --git a/testing/btest/Baseline/signatures.tcp-end-of-match/.stdout b/testing/btest/Baseline/signatures.tcp-end-of-match/.stdout index 4535bc3d33..e34d908ff0 100644 --- a/testing/btest/Baseline/signatures.tcp-end-of-match/.stdout +++ b/testing/btest/Baseline/signatures.tcp-end-of-match/.stdout @@ -1,7 +1,7 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +signature_match, message, 1448 +signature_match with end_of_match, message, 1448, rather than all. (Robin Sommer)\x0a\x0a * Fix parallel make portability portability_match with end_of_match, 1448, rather than all. (Robin Sommer)\x0a\x0a * Fix parallel make portability portability_match, 1448 portability_match_with_msg with end_of_match, custom message, 1448, 69, rather than all. (Robin Sommer)\x0a\x0a * Fix parallel make portability portability_match_with_msg, custom message, 1448 -signature_match, message, 1448 -signature_match with end_of_match, message, 1448, rather than all. (Robin Sommer)\x0a\x0a * Fix parallel make portability