]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2956 in SNORT/snort3 from ~KATHARVE/snort3:http_ooo_injection...
authorTom Peters (thopeter) <thopeter@cisco.com>
Tue, 29 Jun 2021 16:39:28 +0000 (16:39 +0000)
committerTom Peters (thopeter) <thopeter@cisco.com>
Tue, 29 Jun 2021 16:39:28 +0000 (16:39 +0000)
Squashed commit of the following:

commit 89629a45d15511a400494d22d3921540476036ec
Author: Katura Harvey <katharve@cisco.com>
Date:   Fri Jun 25 12:31:16 2021 -0400

    payload_injector: don't inject if there are unflushed S2C TCP packets queued

src/flow/session.h
src/payload_injector/payload_injector.cc
src/payload_injector/payload_injector.h
src/payload_injector/test/payload_injector_test.cc
src/stream/tcp/tcp_stream_session.cc
src/stream/tcp/tcp_stream_session.h

index 1e19849a59050b5fbc60ef4e0119cf030b0c7b05..22146ceeab8e4c9a77da4dbaa79492235586bc91 100644 (file)
@@ -72,6 +72,7 @@ public:
 
     virtual bool is_sequenced(uint8_t /*dir*/) { return true; }
     virtual bool are_packets_missing(uint8_t /*dir*/) { return true; }
+    virtual bool are_client_segments_queued() { return false; }
 
     virtual void disable_reassembly(snort::Flow*) { }
     virtual uint8_t get_reassembly_direction() { return SSN_DIR_NONE; }
index 672c93a5d4cdcaf40a5a9ba60218c4ab32ffbbff..b86a4c2f4d57036f1268160d0f3ab53beb1b2d52 100644 (file)
@@ -25,6 +25,7 @@
 #include "payload_injector.h"
 
 #include "detection/detection_engine.h"
+#include "flow/session.h"
 #include "packet_io/active.h"
 #include "protocols/packet.h"
 #include "service_inspectors/http2_inspect/http2_flow_data.h"
@@ -48,7 +49,8 @@ static const std::map <InjectionReturnStatus, const char*> InjectionErrorToStrin
     { ERR_TRANSLATED_HDRS_SIZE,
       "HTTP/2 translated header size is bigger than expected. Update max size." },
     { ERR_HTTP2_EVEN_STREAM_ID, "HTTP/2 - injection to server initiated stream" },
-    { ERR_PKT_FROM_SERVER, "Packet is from server" }
+    { ERR_PKT_FROM_SERVER, "Packet is from server" },
+    { ERR_CONFLICTING_S2C_TRAFFIC, "Conflicting S2C HTTP traffic in progress" }
 };
 
 InjectionReturnStatus PayloadInjector::inject_http2_payload(Packet* p,
@@ -74,6 +76,11 @@ InjectionReturnStatus PayloadInjector::inject_http2_payload(Packet* p,
             // FIXIT-E mid-frame injection not supported
             status = ERR_HTTP2_MID_FRAME;
         }
+        else if (p->flow->session and
+            p->flow->session->are_client_segments_queued())
+        {
+            status = ERR_CONFLICTING_S2C_TRAFFIC;
+        }
         else
         {
             uint8_t* http2_payload;
@@ -120,8 +127,17 @@ InjectionReturnStatus PayloadInjector::inject_http_payload(Packet* p,
                 else if (!p->flow->gadget || strcmp(p->flow->gadget->get_name(),"http_inspect") ==
                     0)
                 {
-                    payload_injector_stats.http_injects++;
-                    p->active->send_data(p, df, control.http_page, control.http_page_len);
+                    if (p->flow->session and
+                        p->flow->session->are_client_segments_queued())
+                    {
+                        status = ERR_CONFLICTING_S2C_TRAFFIC;
+                        p->active->send_data(p, df, nullptr, 0);    // To send reset
+                    }
+                    else
+                    {
+                        payload_injector_stats.http_injects++;
+                        p->active->send_data(p, df, control.http_page, control.http_page_len);
+                    }
                 }
                 else if (strcmp(p->flow->gadget->get_name(),"http2_inspect") == 0)
                     status = inject_http2_payload(p, control, df);
index 1cb0fe68e2e4610222da3824a05a96b3910d9a93..c95e717a49b16009274ca5109270ac75d1e6ad58 100644 (file)
@@ -40,6 +40,7 @@ enum InjectionReturnStatus : int8_t
     ERR_TRANSLATED_HDRS_SIZE = -7,
     ERR_HTTP2_EVEN_STREAM_ID = -8,
     ERR_PKT_FROM_SERVER = -9,
+    ERR_CONFLICTING_S2C_TRAFFIC = -10,
     // Update InjectionErrorToString when adding/removing error codes
 };
 
index f0feb020a6f6cee209d717844da2639b7e7e45b2..deb39954d695fc86278c3dd632bc97716dce185d 100644 (file)
@@ -430,6 +430,18 @@ TEST(payload_injector_translate_err_test, http2_hdrs_size)
         "HTTP/2 translated header size is bigger than expected. Update max size.") == 0);
 }
 
+TEST(payload_injector_translate_err_test, conflicting_s2c_traffic)
+{
+    Packet p(false);
+    set_configured();
+    p.packet_flags = PKT_STREAM_EST;
+    p.flow = &flow;
+    translation_status = ERR_CONFLICTING_S2C_TRAFFIC;
+    status = PayloadInjector::inject_http_payload(&p, control);
+    const char* err_string = PayloadInjector::get_err_string(status);
+    CHECK(strcmp(err_string,
+        "Conflicting S2C HTTP traffic in progress") == 0);
+}
 int main(int argc, char** argv)
 {
     return CommandLineTestRunner::RunAllTests(argc, argv);
index 0a37dabe48a85d0524ce6afb5b47e7eafde289d6..0d154abf9beaa5c1b575c8d36a662876e3057839 100644 (file)
@@ -229,6 +229,11 @@ bool TcpStreamSession::are_packets_missing(uint8_t dir)
     return false;
 }
 
+bool TcpStreamSession::are_client_segments_queued()
+{
+    return client.reassembler.get_seg_count() > 0;
+}
+
 bool TcpStreamSession::add_alert(Packet* p, uint32_t gid, uint32_t sid)
 {
     TcpReassemblerPolicy& trp = p->ptrs.ip_api.get_src()->equals(flow->client_ip) ?
index f3f33c4ed3ea87296d1ded0000c37c01c5a3afc0..c5f85be9edcd2fb035db04c9cd4f606a29595137 100644 (file)
@@ -49,6 +49,7 @@ public:
     void disable_reassembly(snort::Flow*) override;
     uint8_t get_reassembly_direction() override;
     uint8_t missing_in_reassembled(uint8_t dir) override;
+    bool are_client_segments_queued() override;
 
     bool add_alert(snort::Packet*, uint32_t gid, uint32_t sid) override;
     bool check_alerted(snort::Packet*, uint32_t gid, uint32_t sid) override;