]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #4541: file_api: three files evaluation fix
authorOleg Torubara -X (otorubar - SOFTSERVE INC at Cisco) <otorubar@cisco.com>
Thu, 12 Dec 2024 15:30:18 +0000 (15:30 +0000)
committerSteve Chew (stechew) <stechew@cisco.com>
Thu, 12 Dec 2024 15:30:18 +0000 (15:30 +0000)
Merge in SNORT/snort3 from ~OTORUBAR/snort3:three_files_evaluation_fix to master

Squashed commit of the following:

commit a84f98875d465b61f2ced2e58080b6e18804fe7e
Author: otorubar <otorubar@cisco.com>
Date:   Mon Dec 9 03:19:28 2024 -0800

    file_api: add re_eval flag to fileinfo

src/file_api/file_flows.cc
src/file_api/file_lib.cc
src/file_api/file_lib.h

index 8ea2935aa2d55b3a6e771452262b39d1b6834d7b..eb3249645d22a623edb77483daeeb3b8decfad1f 100644 (file)
@@ -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());
index b2e9d42c75c199a7d169682b4f1c5d883cb4529b..592e8791d860995041559b3925025b1a3333b4f5 100644 (file)
@@ -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
 
index 08cb0f93d4114958a9c532c4be5efdb842b45cee..ef1d7f7770f59798476ac984c0929bca1c617967 100644 (file)
@@ -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;