diff --git a/NEWS b/NEWS index 7c3af61571..d8ffd1bf9a 100644 --- a/NEWS +++ b/NEWS @@ -119,6 +119,9 @@ Changed Functionality - The number of analyzer violation events that can be raised by protocol analyzer instances is now capped by the const ``max_analyzer_violation_events``. + +- The number of analyzer violation events that can be raised by protocol and + file analyzer instances is now capped by the const ``max_analyzer_violation_events``. Its default is 1000 and the main purpose is to prevent analyzers from scheduling too many ``analyzer_violation_info`` events before the DPD ``max_violations`` script-level logic has a chance to run and disable diff --git a/src/file_analysis/Analyzer.cc b/src/file_analysis/Analyzer.cc index 9d33fd2660..dc57f8ea55 100644 --- a/src/file_analysis/Analyzer.cc +++ b/src/file_analysis/Analyzer.cc @@ -7,8 +7,8 @@ #include "zeek/file_analysis/File.h" #include "zeek/file_analysis/Manager.h" -// For analyzer_violation_info -#include "event.bif.netvar_h" +#include "const.bif.netvar_h" // for max_analyzer_violations +#include "event.bif.netvar_h" // for analyzer_violation_info namespace zeek::file_analysis { @@ -38,6 +38,12 @@ Analyzer::Analyzer(RecordValPtr arg_args, File* arg_file) { } +const char* Analyzer::GetAnalyzerName() const + { + assert(tag); + return file_mgr->GetComponentName(tag).c_str(); + } + void Analyzer::AnalyzerConfirmation(zeek::Tag arg_tag) { if ( analyzer_confirmed ) @@ -60,6 +66,16 @@ void Analyzer::AnalyzerConfirmation(zeek::Tag arg_tag) void Analyzer::AnalyzerViolation(const char* reason, const char* data, int len, zeek::Tag arg_tag) { + ++analyzer_violations; + + if ( analyzer_violations > BifConst::max_analyzer_violations ) + { + if ( analyzer_violations == BifConst::max_analyzer_violations + 1 ) + Weird("too_many_analyzer_violations"); + + return; + } + if ( ! analyzer_violation_info ) return; @@ -78,4 +94,9 @@ void Analyzer::AnalyzerViolation(const char* reason, const char* data, int len, event_mgr.Enqueue(analyzer_violation_info, tval, info); } +void Analyzer::Weird(const char* name, const char* addl) + { + zeek::reporter->Weird(GetFile(), name, addl, GetAnalyzerName()); + } + } // namespace zeek::file_analysis diff --git a/src/file_analysis/Analyzer.h b/src/file_analysis/Analyzer.h index 126e3be53c..3ca5c36d74 100644 --- a/src/file_analysis/Analyzer.h +++ b/src/file_analysis/Analyzer.h @@ -83,6 +83,11 @@ public: */ zeek::Tag Tag() const { return tag; } + /** + * @return the name of the analyzer. + */ + const char* GetAnalyzerName() const; + /** * Returns the analyzer instance's internal ID. These IDs are unique * across all analyzers instantiated and can thus be used to @@ -165,6 +170,12 @@ public: virtual void AnalyzerViolation(const char* reason, const char* data = nullptr, int len = 0, zeek::Tag tag = zeek::Tag()); + /** + * Convenience function that forwards directly to the corresponding + * reporter->Weird(file, ...). + */ + void Weird(const char* name, const char* addl = ""); + protected: /** * Constructor. Only derived classes are meant to be instantiated. @@ -195,6 +206,8 @@ private: bool skip; bool analyzer_confirmed; + uint64_t analyzer_violations = 0; + static ID id_counter; }; diff --git a/testing/btest/Baseline/plugins.file/output b/testing/btest/Baseline/plugins.file/output index 0d9cb558fb..b815ff3eb1 100644 --- a/testing/btest/Baseline/plugins.file/output +++ b/testing/btest/Baseline/plugins.file/output @@ -8,14 +8,15 @@ analyzer_confirmation_info, Files::ANALYZER_FOO, FCceqBvpMfirSN0Ri foo_piece, FCceqBvpMfirSN0Ri, The National Center foo_piece, FCceqBvpMfirSN0Ri, net, consult your lo foo_piece, FCceqBvpMfirSN0Ri, most everything else +analyzer_violation_info, Files::ANALYZER_FOO, FCceqBvpMfirSN0Ri, test violation 3, most everything foo_piece, FCceqBvpMfirSN0Ri, low:\x0a\x0a /Mac foo_piece, FCceqBvpMfirSN0Ri, es and directories o -analyzer_violation_info, Files::ANALYZER_FOO, FCceqBvpMfirSN0Ri, test violation 5, es and directori foo_piece, FCceqBvpMfirSN0Ri, r example, here is a +analyzer_violation_info, Files::ANALYZER_FOO, FCceqBvpMfirSN0Ri, test violation 6, r example, here foo_piece, FCceqBvpMfirSN0Ri, application, StuffIt foo_piece, FCceqBvpMfirSN0Ri, tion BinHex by doubl foo_piece, FCceqBvpMfirSN0Ri, laced, or are going +analyzer_violation_info, Files::ANALYZER_FOO, FCceqBvpMfirSN0Ri, test violation 9, laced, or are go foo_piece, FCceqBvpMfirSN0Ri, sers several documen -analyzer_violation_info, Files::ANALYZER_FOO, FCceqBvpMfirSN0Ri, test violation 10, sers several doc foo_piece, FCceqBvpMfirSN0Ri, er or can be printed foo_piece, FCceqBvpMfirSN0Ri, \x0a\x0aBug reports shoul diff --git a/testing/btest/Baseline/plugins.file/weird.log b/testing/btest/Baseline/plugins.file/weird.log new file mode 100644 index 0000000000..99e00cf437 --- /dev/null +++ b/testing/btest/Baseline/plugins.file/weird.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path weird +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer source +#types time string addr port addr port string string bool string string +XXXXXXXXXX.XXXXXX - - - - - too_many_analyzer_violations FCceqBvpMfirSN0Ri F zeek FOO +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/plugins/file-plugin/src/Foo.cc b/testing/btest/plugins/file-plugin/src/Foo.cc index 41b9eac52f..fe4329a1c2 100644 --- a/testing/btest/plugins/file-plugin/src/Foo.cc +++ b/testing/btest/plugins/file-plugin/src/Foo.cc @@ -25,7 +25,7 @@ bool Foo::DeliverStream(const u_char* data, uint64_t len) AnalyzerConfirmation(); zeek::event_mgr.Enqueue(foo_piece, GetFile()->ToVal(), zeek::make_intrusive(new zeek::String(data, len, 0))); - if ( ++i % 5 == 0 ) + if ( ++i % 3 == 0 ) { uint64_t threshold = 16; AnalyzerViolation(zeek::util::fmt("test violation %d", i), diff --git a/testing/btest/plugins/file.zeek b/testing/btest/plugins/file.zeek index 77747bc4d2..cb622240f8 100644 --- a/testing/btest/plugins/file.zeek +++ b/testing/btest/plugins/file.zeek @@ -5,6 +5,10 @@ # @TEST-EXEC: echo === >>output # @TEST-EXEC: ZEEK_PLUGIN_PATH=`pwd` zeek -r $TRACES/ftp/retr.trace %INPUT >>output # @TEST-EXEC: TEST_DIFF_CANONIFIER= btest-diff output +# @TEST-EXEC: btest-diff weird.log + +# Suppress AnalyzerViolation() after the third one and create a weird.log. +redef max_analyzer_violations = 3; event file_new(f: fa_file) {