]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1497 in SNORT/snort3 from ~MIREDDEN/snort3:fix_sticky_buffer_dupl...
authorTom Peters (thopeter) <thopeter@cisco.com>
Thu, 31 Jan 2019 18:43:36 +0000 (13:43 -0500)
committerTom Peters (thopeter) <thopeter@cisco.com>
Thu, 31 Jan 2019 18:43:36 +0000 (13:43 -0500)
Squashed commit of the following:

commit 91637b20ce8f365061a607e9233b1a239629fc72
Author: Mike Redden <miredden@cisco.com>
Date:   Mon Jan 28 17:10:32 2019 -0500

    snort2lua: fix sticky buffer duplication

tools/snort2lua/data/data_types/dt_rule.cc
tools/snort2lua/data/data_types/dt_rule_option.cc
tools/snort2lua/data/data_types/dt_rule_option.h
tools/snort2lua/data/data_types/dt_rule_suboption.h
tools/snort2lua/rule_states/rule_pcre.cc

index 9c6c28ae6fd0c35359c367e2b9910fd4124495fa..f47fe113343ed13d5fa5c504b935e8f54fdc51db 100644 (file)
@@ -116,20 +116,27 @@ void Rule::add_suboption(const std::string& keyword, const std::string& val)
 
 void Rule::set_curr_options_buffer(const std::string& new_buffer, bool add_option)
 {
-    /* set the buffer if
-     * 1) No buffer has been set and this is not the default "pkt_data" buffer
-     * 2) The sticky buffer is set and is not equal to the new buffer
-     */
-    if ( (sticky_buffer.empty() && new_buffer != "pkt_data") ||
-        (!sticky_buffer.empty() && sticky_buffer != new_buffer) )
+    if (new_buffer == "pkt_data")
     {
-        RuleOption* new_opt = new RuleOption(new_buffer);
-        if ( add_option )
-            options.push_back(new_opt);
-        else
-            options.insert(options.end() - 1, new_opt);
-        sticky_buffer = new_buffer;
+        if (sticky_buffer.empty())
+        {
+            sticky_buffer = "pkt_data";
+            return;
+        }
+
+        if (sticky_buffer == "pkt_data")
+        {
+            return;
+        }
     }
+
+    RuleOption* new_opt = new RuleOption(new_buffer);
+    if ( add_option )
+        options.push_back(new_opt);
+    else
+        options.insert(options.end() - 1, new_opt);
+
+    sticky_buffer = new_buffer;
 }
 
 std::ostream& operator<<(std::ostream& out, const Rule& rule)
@@ -181,23 +188,28 @@ void Rule::resolve_pcre_buffer_options()
 {
     std::string curr_sticky_buffer = "";
     const std::string service = get_option("service");
-    bool service_sip = (service.find("sip") != std::string::npos);
-    bool no_service_http = (service.find("http") == std::string::npos);
+    const bool service_sip = (service.find("sip") != std::string::npos);
+    const bool no_service_http = (service.find("http") == std::string::npos);
     std::string new_buffer;
     std::vector<RuleOption*>::iterator iter = options.begin();
+    std::vector<RuleOption*>::iterator next_opt_iter;
 
     while (iter != options.end())
     {
         std::string name = (*iter)->get_name();
 
-        if (name == "pcre_P_option_body" || name == "pcre_H_option_header")
+        if (name == "pcre_P_option_body" ||
+            name == "pcre_P_option_body_rel" ||
+            name == "pcre_H_option_header" ||
+            name == "pcre_H_option_header_rel")
         {
             delete(*iter);
             iter = options.erase(iter);
 
             if (service_sip)
             {
-                if (name == "pcre_P_option_body")
+                if (name == "pcre_P_option_body" ||
+                    name == "pcre_P_option_body_rel")
                 {
                     new_buffer = "sip_body";
                 }
@@ -208,7 +220,8 @@ void Rule::resolve_pcre_buffer_options()
             }
             else
             {
-                if (name == "pcre_P_option_body")
+                if (name == "pcre_P_option_body" ||
+                    name == "pcre_P_option_body_rel")
                 {
                     if (no_service_http)
                     {
@@ -226,7 +239,11 @@ void Rule::resolve_pcre_buffer_options()
                 }
             }
 
-            if (curr_sticky_buffer != new_buffer)
+            /* Add sticky buffer option if not equal to current,
+             * or if the pcre option is not relative */
+            if (curr_sticky_buffer != new_buffer ||
+                (name != "pcre_P_option_body_rel" &&
+                name != "pcre_H_option_header_rel"))
             {
                 curr_sticky_buffer = new_buffer;
                 RuleOption* new_opt = new RuleOption(new_buffer);
@@ -239,6 +256,14 @@ void Rule::resolve_pcre_buffer_options()
             name == "dce_stub_data" ||
             name == "dnp3_data" ||
             name == "modbus_data" ||
+            name == "sip_header" ||
+            name == "sip_body")
+        {
+            curr_sticky_buffer = name;
+            ++iter;
+        }
+        else if (name == "http_header" ||
+            name == "http_client_body" ||
             name == "http_cookie" ||
             name == "http_method" ||
             name == "http_raw_cookie" ||
@@ -247,19 +272,26 @@ void Rule::resolve_pcre_buffer_options()
             name == "http_stat_code" ||
             name == "http_stat_msg" ||
             name == "http_uri")
-        {
-            curr_sticky_buffer = name;
-            ++iter;
-        }
-        else if (name == "http_header" ||
-            name == "http_client_body" ||
-            name == "sip_header" ||
-            name == "sip_body")
         {
             if (curr_sticky_buffer == name)
             {
-                delete(*iter);
-                iter = options.erase(iter);
+                next_opt_iter = std::next(iter, 1);
+                if (next_opt_iter != options.end())
+                {
+                    if ((*next_opt_iter)->is_relative_content())
+                    {
+                        delete(*iter);
+                        iter = options.erase(iter);
+                    }
+                    else
+                    {
+                        ++iter;
+                    }
+                }
+                else
+                {
+                    ++iter;
+                }
             }
             else
             {
index a4d6f5d73046d0ad52336a5cf3b69f3c36dca6af..af01e1e3364008356a73a6a9ce1623e527648a6e 100644 (file)
@@ -51,6 +51,21 @@ bool RuleOption::add_suboption(const std::string& subopt_name,
     return true;
 }
 
+bool RuleOption::is_relative_content()
+{
+    if (get_name() == "content")
+    {
+        for (auto rso : sub_options)
+        {
+            const std::string subopt_name = rso->get_name();
+            if (subopt_name == "within" || subopt_name == "distance")
+                return true;
+        }
+    }
+
+    return false;
+}
+
 std::ostream& operator<<(std::ostream& out, const RuleOption& opt)
 {
     bool first_print = true;
index 8d9dc83d853e652f9c94fbb5d48126b0f99ea028..a2ffa8190fd0ff019bf136fa7f9c015a5c38accf 100644 (file)
@@ -35,11 +35,13 @@ public:
 
     inline const std::string& get_name() { return name; }
     inline const std::string& get_value() { return value; }
-    inline void update_value(std::string& new_value) { value = new_value;}
+    inline void update_value(std::string& new_value) { value = new_value; }
 
     bool add_suboption(const std::string& name);
     bool add_suboption(const std::string& name, const std::string& val);
 
+    bool is_relative_content();
+
     // overloading operators
     friend std::ostream& operator<<(std::ostream&, const RuleOption&);
 
index e40d856021b2aede3458b52a8f08a14fabc3f7c2..53c13649e27568c5c97fbdf8e9fd8405e2e70693 100644 (file)
@@ -31,6 +31,8 @@ public:
     RuleSubOption(const std::string& name, const std::string& val);
     virtual ~RuleSubOption() = default;
 
+    inline const std::string& get_name() { return name; }
+
     // overloading operators
     friend std::ostream& operator<<(std::ostream&, const RuleSubOption&);
 
index 0ff7c6c6334d13cc34f1e70be5bd028b3503c0d6..c3e79ffa1a78d0c3c1962d7222445ab99a1cc8a2 100644 (file)
@@ -141,8 +141,15 @@ bool Pcre::convert(std::istringstream& data_stream)
 
     rule_api.add_option("pcre", pattern + new_opts);
 
-    if ( !relative )
-        rule_api.set_curr_options_buffer(buffer);
+    if ( relative )
+    {
+        if (buffer == "pcre_P_option_body")
+            buffer = "pcre_P_option_body_rel";
+        else if (buffer == "pcre_H_option_header")
+            buffer = "pcre_H_option_header_rel";
+    }
+
+    rule_api.set_curr_options_buffer(buffer);
 
     return set_next_rule_state(data_stream);
 }