]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2083 in SNORT/snort3 from ~SBAIGAL/snort3:so_proxy to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Thu, 26 Mar 2020 22:53:55 +0000 (22:53 +0000)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Thu, 26 Mar 2020 22:53:55 +0000 (22:53 +0000)
Squashed commit of the following:

commit f19ea58fa5e667524c554164ab956346e1abe04a
Author: Steven Baigal (sbaigal) <sbaigal@cisco.com>
Date:   Tue Mar 10 18:11:14 2020 -0400

    so_rule: fix reload of shared object rules that use flow data

    add tracking SO rule flow data with so_proxy inspector

14 files changed:
src/flow/CMakeLists.txt
src/flow/flow.cc
src/flow/flow.h
src/flow/flow_data.cc [new file with mode: 0644]
src/flow/flow_data.h [new file with mode: 0644]
src/flow/test/CMakeLists.txt
src/flow/test/flow_test.cc
src/framework/base_api.h
src/host_tracker/test/host_cache_module_test.cc
src/managers/coreinit.lua
src/managers/plugin_manager.cc
src/managers/so_manager.cc
src/managers/so_manager.h
src/network_inspectors/appid/client_plugins/test/client_plugin_mock.h

index fb5a7d0368d612819084551c5943b3c67d4e9b2e..34ff1be249a16e48faf753940d4213ccfa1fbd4c 100644 (file)
@@ -1,6 +1,7 @@
 set (FLOW_INCLUDES
     expect_cache.h
     flow.h
+    flow_data.h
     flow_key.h
     flow_stash.h
     ha.h
@@ -16,6 +17,7 @@ add_library (flow OBJECT
     flow_config.h
     flow_control.cc
     flow_control.h
+    flow_data.cc
     flow_key.cc
     flow_stash.cc
     flow_stash.h
index d9a2e2fd5f83dac1ede938bd186d4e22fd9219ea..ffac79d048f6a90c226de4a015acd9b408563bb2 100644 (file)
@@ -28,7 +28,6 @@
 #include "flow/session.h"
 #include "framework/data_bus.h"
 #include "ips_options/ips_flowbits.h"
-#include "memory/memory_cap.h"
 #include "protocols/packet.h"
 #include "sfip/sf_ip.h"
 #include "utils/bitop.h"
 
 using namespace snort;
 
-unsigned FlowData::flow_data_id = 0;
-
-FlowData::FlowData(unsigned u, Inspector* ph)
-{
-    assert(u > 0);
-    id = u;
-    handler = ph;
-    prev = next = nullptr;
-    if ( handler )
-        handler->add_ref();
-}
-
-FlowData::~FlowData()
-{
-    if ( handler )
-        handler->rem_ref();
-
-    assert(mem_in_use == 0);
-}
-
-void FlowData::update_allocations(size_t n)
-{
-    memory::MemoryCap::free_space(n);
-    memory::MemoryCap::update_allocations(n);
-    mem_in_use += n;
-}
-
-void FlowData::update_deallocations(size_t n)
-{
-    assert(mem_in_use >= n);
-    memory::MemoryCap::update_deallocations(n);
-    mem_in_use -= n;
-}
-
-size_t FlowData::size_of()
-{ return 1024; }  // FIXIT-H remove this default impl
-
 Flow::Flow()
 {
     memset(this, 0, sizeof(*this));
index 5f02ae58db7fa4fbd22b9c29a45f3f3fbf272ed2..8e2bd8b0f8a8c1bbdf01ed0be1829b4331d268af 100644 (file)
@@ -30,6 +30,7 @@
 #include <sys/time.h>
 
 #include "detection/ips_context_chain.h"
+#include "flow/flow_data.h"
 #include "flow/flow_stash.h"
 #include "framework/data_bus.h"
 #include "framework/decode_data.h"
@@ -108,42 +109,6 @@ struct Packet;
 
 typedef void (* StreamAppDataFree)(void*);
 
-class SO_PUBLIC FlowData
-{
-public:
-    FlowData(unsigned u, Inspector* = nullptr);
-    virtual ~FlowData();
-
-    unsigned get_id()
-    { return id; }
-
-    static unsigned create_flow_data_id()
-    { return ++flow_data_id; }
-
-    void update_allocations(size_t);
-    void update_deallocations(size_t);
-    Inspector* get_handler() { return handler; }
-
-    // return fixed size (could be an approx avg)
-    // this must be fixed for life of flow data instance
-    // track significant supplemental allocations with the above updaters
-    virtual size_t size_of() = 0;
-
-    virtual void handle_expected(Packet*) { }
-    virtual void handle_retransmit(Packet*) { }
-    virtual void handle_eof(Packet*) { }
-
-public:  // FIXIT-L privatize
-    FlowData* next;
-    FlowData* prev;
-
-private:
-    static unsigned flow_data_id;
-    Inspector* handler;
-    size_t mem_in_use = 0;
-    unsigned id;
-};
-
 struct FlowStats
 {
     uint64_t client_pkts;
diff --git a/src/flow/flow_data.cc b/src/flow/flow_data.cc
new file mode 100644 (file)
index 0000000..af6f9b0
--- /dev/null
@@ -0,0 +1,71 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+// flow_data.cc author Russ Combs <rucombs@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "flow_data.h"
+
+#include <cassert>
+
+#include "framework/inspector.h"
+#include "main/snort_config.h"
+#include "managers/so_manager.h"
+#include "memory/memory_cap.h"
+
+using namespace snort;
+
+unsigned FlowData::flow_data_id = 0;
+
+FlowData::FlowData(unsigned u, Inspector* ph)
+{
+    assert(u > 0);
+    id = u;
+    handler = ph;
+    prev = next = nullptr;
+    if ( handler )
+        handler->add_ref();
+}
+
+FlowData::~FlowData()
+{
+    if ( handler )
+        handler->rem_ref();
+
+    assert(mem_in_use == 0);
+}
+
+void FlowData::update_allocations(size_t n)
+{
+    memory::MemoryCap::free_space(n);
+    memory::MemoryCap::update_allocations(n);
+    mem_in_use += n;
+}
+
+void FlowData::update_deallocations(size_t n)
+{
+    assert(mem_in_use >= n);
+    memory::MemoryCap::update_deallocations(n);
+    mem_in_use -= n;
+}
+
+RuleFlowData::RuleFlowData(unsigned u) : FlowData(u, 
+    SnortConfig::get_conf()->so_rules->proxy) { }
+
diff --git a/src/flow/flow_data.h b/src/flow/flow_data.h
new file mode 100644 (file)
index 0000000..6a19e23
--- /dev/null
@@ -0,0 +1,77 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+// flow_data.h author Russ Combs <rucombs@cisco.com>
+
+#ifndef FLOW_DATA_H
+#define FLOW_DATA_H
+
+#include "main/snort_types.h"
+
+namespace snort
+{
+class Inspector;
+struct Packet;
+
+class SO_PUBLIC FlowData
+{
+public:
+    FlowData(unsigned u, Inspector* = nullptr);
+    virtual ~FlowData();
+
+    unsigned get_id()
+    { return id; }
+
+    static unsigned create_flow_data_id()
+    { return ++flow_data_id; }
+
+    void update_allocations(size_t);
+    void update_deallocations(size_t);
+    Inspector* get_handler() { return handler; }
+
+    // return fixed size (could be an approx avg)
+    // this must be fixed for life of flow data instance
+    // track significant supplemental allocations with the above updaters
+    virtual size_t size_of() = 0;
+
+    virtual void handle_expected(Packet*) { }
+    virtual void handle_retransmit(Packet*) { }
+    virtual void handle_eof(Packet*) { }
+
+public:  // FIXIT-L privatize
+    FlowData* next;
+    FlowData* prev;
+
+private:
+    static unsigned flow_data_id;
+    Inspector* handler;
+    size_t mem_in_use = 0;
+    unsigned id;
+};
+
+// The flow data created from SO rules must use RuleFlowData
+// to support reload
+class SO_PUBLIC RuleFlowData : public FlowData
+{
+protected:
+    RuleFlowData(unsigned u);
+public:
+    virtual ~RuleFlowData() { }
+};
+
+}
+#endif
index df99e24f79e3a6dbc11f343f3151ba9269b0867c..fe0a2b09f4448931875b024e2882286626e6fc5b 100644 (file)
@@ -23,5 +23,7 @@ add_cpputest( flow_cache_test
 add_cpputest( session_test )
 
 add_cpputest( flow_test
-    SOURCES ../flow.cc
+    SOURCES
+        ../flow.cc
+        ../flow_data.cc
 )
index cac9f8a8bff8c6938f70933b44829dd1ad9d6165..75998729377a2f9b81d8d522b7b607ff93b4495e 100644 (file)
 #include "config.h"
 #endif
 
-#include "protocols/ip.h"
-#include "protocols/layer.h"
-#include "protocols/packet.h"
+#include "detection/detection_engine.h"
 #include "flow/flow.h"
 #include "flow/flow_stash.h"
 #include "flow/ha.h"
-#include "main/snort_debug.h"
 #include "framework/inspector.h"
 #include "framework/data_bus.h"
+#include "main/snort_config.h"
+#include "main/snort_debug.h"
 #include "memory/memory_cap.h"
-#include "detection/detection_engine.h"
+#include "protocols/ip.h"
+#include "protocols/layer.h"
+#include "protocols/packet.h"
 
 #include <CppUTest/CommandLineTestRunner.h>
 #include <CppUTest/TestHarness.h>
@@ -82,6 +83,8 @@ const Layer* layer::get_mpls_layer(const Packet* const) { return nullptr; }
 
 void DataBus::publish(const char*, Packet*, Flow*) {}
 
+SnortConfig* SnortConfig::get_conf() { return nullptr; }
+
 TEST_GROUP(nondefault_timeout)
 {
     void setup() override
index 06d9558682fc5610c24d2b870cf6fb89fcf7eeaf..00d181a518855b26f884f818d83e9503b6e1c46b 100644 (file)
@@ -29,7 +29,7 @@
 
 // this is the current version of the base api
 // must be prefixed to subtype version
-#define BASE_API_VERSION 1
+#define BASE_API_VERSION 2
 
 // set options to API_OPTIONS to ensure compatibility
 #ifndef API_OPTIONS
index e048064c075328374c903607e1a09c6eb94824e7..0db2a0b78cf6a6eafdb31a56e128322981474214 100644 (file)
@@ -82,6 +82,14 @@ HostCacheAllocIp<T>::HostCacheAllocIp()
     lru = &host_cache;
 }
 
+template <class T>
+void HostCacheAlloc<T>::deallocate(T* p, std::size_t n) noexcept
+{
+    size_t sz = n*sizeof(T);
+    std::allocator<T>::deallocate(p, n);
+    lru->update( -(int) sz);
+}
+
 TEST_GROUP(host_cache_module)
 {
     void setup() override
index 04b114fa243d85d4e74e6ca42bc698928ad83cb3..7f607870dc494425b3de5185c0c47c4e318551c9 100644 (file)
@@ -38,6 +38,7 @@ output = { }
 packets = { }
 process = { }
 search_engine = { }
+so_proxy = { }
 
 -- exceptions:
 
index 63fc5a3f1b3a6e1bbd02d19a6c7d1358d29ce8e4..172d65d004c9f15a26fb026b8b1fdfb488c338a2 100644 (file)
@@ -398,6 +398,8 @@ void PluginManager::load_plugins(const BaseApi** lp)
 
 void PluginManager::load_plugins(const std::string& paths)
 {
+    SoManager::load_so_proxy();
+
     // dynamic plugins
     if ( !paths.empty() )
         ::load_plugins(paths);
index 8c8c8b046a89e3d31504396d4f29291ceb5e8140..f2eeec4a9d1d8a780a8c7789c5abb71cb05ac884 100644 (file)
@@ -33,6 +33,9 @@
 #include <sstream>
 
 #include "log/messages.h"
+#include "framework/decode_data.h"
+#include "framework/inspector.h"
+#include "framework/module.h"
 #include "main/snort_config.h"
 #include "parser/parse_so_rule.h"
 
@@ -337,3 +340,92 @@ void SoManager::rule_to_text(const char* delim)
     cout << "static const unsigned rule_" << var << "_len = 0;" << endl;
 }
 
+//-------------------------------------------------------------------------
+// so_proxy inspector
+//-------------------------------------------------------------------------
+static const char* sp_name = "so_proxy";
+static const char* sp_help = "a proxy inspector to track flow data from SO rules (internal use only)";
+class SoProxy : public Inspector
+{
+public:
+    void eval(Packet*) override { }
+    bool configure(SnortConfig* sc) override
+    {
+        for( auto i : sc->so_rules->handles )
+            handles.emplace_back(i);
+        sc->so_rules->proxy = this;
+        return true;
+    }
+    ~SoProxy() override { handles.clear(); }
+
+private:
+    std::list<SoHandlePtr> handles;
+};
+
+static const Parameter sp_params[] =
+{
+    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+class SoProxyModule : public Module
+{
+public:
+    SoProxyModule() : Module(sp_name, sp_help, sp_params) { }
+    Usage get_usage() const override
+    { return GLOBAL; }
+};
+
+static Module* mod_ctor()
+{ return new SoProxyModule; }
+
+static void mod_dtor(Module* m)
+{ delete m; }
+
+static Inspector* sp_ctor(Module*)
+{
+    return new SoProxy;
+}
+
+static void sp_dtor(Inspector* p)
+{
+    delete p;
+}
+
+static const InspectApi so_proxy_api
+{
+    {
+        PT_INSPECTOR,
+        sizeof(InspectApi),
+        INSAPI_VERSION,
+        0,
+        API_RESERVED,
+        API_OPTIONS,
+        sp_name,
+        sp_help,
+        mod_ctor,
+        mod_dtor
+    },
+    IT_PASSIVE,
+    PROTO_BIT__NONE,
+    nullptr, // buffers
+    nullptr, // service
+    nullptr, // pinit
+    nullptr, // pterm
+    nullptr, // tinit,
+    nullptr, // tterm,
+    sp_ctor,
+    sp_dtor,
+    nullptr, // ssn
+    nullptr  // reset
+};
+
+const BaseApi* so_proxy_plugins[] =
+{
+    &so_proxy_api.base,
+    nullptr
+};
+
+void SoManager::load_so_proxy()
+{
+    PluginManager::load_plugins(so_proxy_plugins);
+}
index bbcc89e1997b488c455567923610c6e91ea073fe..03ea4d8b9f9ea64099504a698cc50b4a96be3b33 100644 (file)
@@ -29,6 +29,7 @@
 namespace snort
 {
 struct SnortConfig;
+class Inspector;
 }
 
 //-------------------------------------------------------------------------
@@ -36,6 +37,7 @@ struct SoRules
 {
     std::list<const SoApi*> api;
     std::list<SoHandlePtr> handles;
+    snort::Inspector* proxy = nullptr;
     ~SoRules();
 };
 
@@ -56,6 +58,7 @@ public:
     static void rule_to_hex(const char* file);
     static void rule_to_text(const char* file);
     static void dump_rule_stubs(const char*, snort::SnortConfig*);
+    static void load_so_proxy();
 };
 
 #endif
index 17010d100cd7f73493dc530db52e8e0a4ba1d40a..e01a97e4a3d5897b624c0773cbea0dd127630a6d 100644 (file)
@@ -101,6 +101,7 @@ AppIdConfig::~AppIdConfig() = default;
 
 // Stubs for AppIdPegCounts
 void AppIdPegCounts::inc_payload_count(AppId) { }
+void AppIdPegCounts::inc_client_count(AppId) { }
 
 THREAD_LOCAL AppIdStats appid_stats;