From: Oleg Torubara -X (otorubar - SOFTSERVE INC at Cisco) Date: Thu, 12 Dec 2024 15:30:18 +0000 (+0000) Subject: Pull request #4541: file_api: three files evaluation fix X-Git-Tag: 3.6.1.0~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c1a620d97bc70d64283cacd4307b2cccb9e86837;p=thirdparty%2Fsnort3.git Pull request #4541: file_api: three files evaluation fix Merge in SNORT/snort3 from ~OTORUBAR/snort3:three_files_evaluation_fix to master Squashed commit of the following: commit a84f98875d465b61f2ced2e58080b6e18804fe7e Author: otorubar Date: Mon Dec 9 03:19:28 2024 -0800 file_api: add re_eval flag to fileinfo --- diff --git a/src/file_api/file_flows.cc b/src/file_api/file_flows.cc index 8ea2935aa..eb3249645 100644 --- a/src/file_api/file_flows.cc +++ b/src/file_api/file_flows.cc @@ -350,6 +350,10 @@ bool FileFlows::file_process(Packet* p, uint64_t file_id, const uint8_t* file_da "file_process:context missing, returning \n"); return false; } + + if (context->has_to_re_eval() and context->processing_complete) + context->reset(); + context->set_weak_file_name((const char*)fname, name_size); context->set_weak_url((const char*)url, url_size); context->set_host(host_name.c_str(), host_name.size()); diff --git a/src/file_api/file_lib.cc b/src/file_api/file_lib.cc index b2e9d42c7..592e8791d 100644 --- a/src/file_api/file_lib.cc +++ b/src/file_api/file_lib.cc @@ -510,6 +510,50 @@ void FileContext::check_policy(Flow* flow, FileDirection dir, FilePolicyBase* po policy->policy_check(flow, this); } +void FileInfo::reset() +{ + verdict = FILE_VERDICT_UNKNOWN; + processing_complete = false; + set_file_size(0); + reset_sha(); + if (is_file_name_set()) + unset_file_name(); +} + +void FileInfo::set_re_eval() +{ + re_eval = true; +} + +bool FileInfo::has_to_re_eval() +{ + return re_eval; +} + +void FileInfo::unset_re_eval() +{ + re_eval = false; +} + +void FileContext::remove_segments() +{ + if (file_segments == nullptr) + return; + delete file_segments; + file_segments = nullptr; +} + +void FileContext::reset() +{ + verdict = FILE_VERDICT_UNKNOWN; + processing_complete = false; + set_file_size(0); + reset_sha(); + if (is_file_name_set()) + unset_file_name(); + remove_segments(); +} + /* * Return: * true: continue processing/log/block this file @@ -1010,7 +1054,7 @@ TEST_CASE ("unset_file_name", "[file_info]") FI_TEST info; info.set_file_name("test", 4); - CHECK ( true == info.is_file_name_set()); + CHECK (true == info.is_file_name_set()); info.unset_file_name(); CHECK (false == info.is_file_name_set()); @@ -1023,5 +1067,28 @@ TEST_CASE ("get_url", "[file_info]") CHECK (info.get_url() == std::string("/var/tmp/test.pdf")); } +TEST_CASE ("reset", "[file_info]") +{ + FI_TEST info; + info.verdict = FILE_VERDICT_BLOCK; + info.processing_complete = true; + info.set_file_name("test", 4); + + info.reset(); + + CHECK (false == info.processing_complete); + CHECK (FILE_VERDICT_UNKNOWN == info.verdict); + CHECK (false == info.is_file_name_set()); +} + +TEST_CASE ("re_eval", "[file_info]") +{ + FI_TEST info; + CHECK (false == info.has_to_re_eval()); + info.set_re_eval(); + CHECK (true == info.has_to_re_eval()); + info.unset_re_eval(); + CHECK (false == info.has_to_re_eval()); +} #endif diff --git a/src/file_api/file_lib.h b/src/file_api/file_lib.h index 08cb0f93d..ef1d7f777 100644 --- a/src/file_api/file_lib.h +++ b/src/file_api/file_lib.h @@ -94,6 +94,7 @@ public: void set_file_data(UserFileDataBase* fd); UserFileDataBase* get_file_data() const; void copy(const FileInfo& other, bool clear_data = true); + void reset(); // Preserve the file in memory until it is released // The file reserved will be returned and it will be detached from file context/session FileCaptureState reserve_file(FileCapture*& dest); @@ -106,6 +107,14 @@ public: std::mutex user_file_data_mutex; struct timeval pending_expire_time = {0, 0}; + void set_re_eval(); + bool has_to_re_eval(); + void unset_re_eval(); + + // Flag which indicates that the file requires re-eval even though it was fully processed before. + // If "true" and the policy was checked - has to be set to "false" again. + bool re_eval = false; + protected: std::string file_name; bool file_name_set = false; @@ -164,6 +173,10 @@ public: bool is_cacheable() { return cacheable; } bool segments_queued() { return (file_segments != nullptr); } + // Configuration functions + void remove_segments(); + void reset(); + private: uint64_t processed_bytes = 0; void* file_type_context;