]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #4114: ips_context alt_buffer update
authorYehor Velykozhon -X (yvelykoz - SOFTSERVE INC at Cisco) <yvelykoz@cisco.com>
Mon, 12 Feb 2024 13:45:05 +0000 (13:45 +0000)
committerOleksii. Shumeiko -X (oshumeik - SOFTSERVE INC at Cisco) <oshumeik@cisco.com>
Mon, 12 Feb 2024 13:45:05 +0000 (13:45 +0000)
Merge in SNORT/snort3 from ~YVELYKOZ/snort3:ips_context_allocation_upd to master

Squashed commit of the following:

commit ee31592668aae0a799f3a54298eb594ca94698fd
Author: Yehor Velykozhon <yvelykoz@cisco.com>
Date:   Tue Nov 21 14:59:36 2023 +0200

    ips_context: add lazy-allocation of alt buffer

13 files changed:
src/detection/detection_engine.cc
src/detection/detection_engine.h
src/detection/detection_util.h
src/detection/fp_detect.cc
src/framework/cursor.cc
src/ips_options/ips_base64.cc
src/loggers/alert_fast.cc
src/network_inspectors/port_scan/port_scan.cc
src/service_inspectors/ftp_telnet/pp_ftp.cc
src/service_inspectors/ftp_telnet/pp_telnet.cc
src/service_inspectors/ftp_telnet/telnet.cc
src/service_inspectors/rpc_decode/rpc_decode.cc
src/service_inspectors/smtp/smtp_util.cc

index e659b7701fd10de6bd7d354afaed3d96f255598a..771f6b4d8a8fd066f94143a1fe43164d23931bcd 100644 (file)
@@ -297,12 +297,6 @@ uint8_t* DetectionEngine::get_next_buffer(unsigned& max)
     return Analyzer::get_switcher()->get_next()->buf;
 }
 
-DataBuffer& DetectionEngine::get_alt_buffer(Packet* p)
-{
-    assert(p);
-    return p->context->alt_data;
-}
-
 void DetectionEngine::set_file_data(const DataPointer& dp)
 {
     auto c = Analyzer::get_switcher()->get_context();
index dd73347ca94b270641bd9d5d067aab9c1695b79c..e86fc7c8b72598ac02cfc1b3f1906aa0a0d858d9 100644 (file)
@@ -74,7 +74,9 @@ public:
     static const DataPointer& get_file_data(const IpsContext*, uint64_t& id, bool& drop_sse, bool& no_sse);
 
     static uint8_t* get_buffer(unsigned& max);
-    static struct DataBuffer& get_alt_buffer(Packet*);
+    static inline DataPointer get_alt_buffer(const Packet*);
+    static inline DataBuffer& acquire_alt_buffer(const Packet*);
+    static inline void reset_alt_buffer(Packet*);
 
     static void set_data(unsigned id, IpsContextData*);
     static IpsContextData* get_data(unsigned id);
@@ -123,6 +125,29 @@ private:
     IpsContext* context;
 };
 
+DataPointer DetectionEngine::get_alt_buffer(const Packet* p)
+{
+    assert(p);
+    auto& alt_buf = p->context->alt_data;
+
+    return { alt_buf.data, alt_buf.len };
+}
+
+DataBuffer& DetectionEngine::acquire_alt_buffer(const Packet* p)
+{
+    assert(p);
+
+    auto& alt_buf = p->context->alt_data;
+
+    if (!alt_buf.data)
+        alt_buf.allocate_data();
+
+    return alt_buf;
+}
+
+void snort::DetectionEngine::reset_alt_buffer(Packet *p)
+{ p->context->alt_data.len = 0; }
+
 static inline void set_file_data(const uint8_t* p, unsigned n)
 {
     DataPointer dp { p, n };
index 0f583100ca79aa8a23097aba05567fa7c550b48a..7c44adef24a80b0e7569a2ea73b6fd2bc63a0511 100644 (file)
@@ -24,6 +24,8 @@
 // this is a legacy junk-drawer file that needs to be refactored
 // it provides file and alt data and event trace foo.
 
+#include <cassert>
+
 #include "actions/actions.h"
 #include "main/snort_config.h"
 
@@ -39,8 +41,22 @@ struct DataPointer
 
 struct DataBuffer
 {
-    uint8_t data[DECODE_BLEN];
-    unsigned len;
+    static constexpr unsigned decode_blen = DECODE_BLEN;
+
+    DataBuffer() = default;
+    DataBuffer(const DataBuffer&) = delete;
+    DataBuffer& operator=(const DataBuffer&) = delete;
+    ~DataBuffer()
+    { delete [] data; }
+
+    void allocate_data()
+    {
+        assert(nullptr == data);
+        const_cast<uint8_t*&>(data) = new uint8_t[DECODE_BLEN];
+    }
+
+    uint8_t* const data = nullptr;
+    unsigned len = 0;
 };
 
 struct MatchedBuffer
index c9e97556df4adf860da1c64e9f793e8f0ad7c3af..df3c3c6119dea6c3ddd74e83d702d82500b44209 100644 (file)
@@ -914,7 +914,7 @@ static int fp_search(RuleGroup* port_group, Packet* p, bool srvc)
                 {
                     // need to add a norm_data keyword or telnet, rpc_decode, smtp keywords
                     // until then we must use the standard packet mpse
-                    const DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
+                    const DataPointer& buf = DetectionEngine::get_alt_buffer(p);
 
                     if ( buf.len )
                     {
index 74adb2f1769e48b6e24e3c2c2cef014d36d8bf01..5a280fdc2f20eea7d0431eb51e631e58696c4601 100644 (file)
@@ -103,8 +103,7 @@ void Cursor::reset(Packet* p)
 {
     if (p->flow and p->flow->gadget)
     {
-        const DataBuffer& alt_buf = DetectionEngine::get_alt_buffer(p);
-
+        const DataPointer& alt_buf = DetectionEngine::get_alt_buffer(p);
         if (alt_buf.len)
         {
             set("alt_data", alt_buf.data, alt_buf.len);
index b2f13147b4a32eec80c680afde2482e9e99c49a1..6b56627cbaccf9a3d6d9f9a1a7f5a258a3c03cf8 100644 (file)
@@ -117,7 +117,7 @@ IpsOption::EvalStatus Base64DecodeOption::eval(Cursor& c, Packet* p)
 {
     // cppcheck-suppress unreadVariable
     RuleProfile profile(base64PerfStats);
-    DataBuffer& base64_decode_buffer = DetectionEngine::get_alt_buffer(p);
+    DataBuffer& base64_decode_buffer = DetectionEngine::acquire_alt_buffer(p);
     base64_decode_buffer.len = 0;
 
     Base64DecodeData* idx = (Base64DecodeData*)&config;
@@ -153,7 +153,7 @@ IpsOption::EvalStatus Base64DecodeOption::eval(Cursor& c, Packet* p)
     }
 
     if (sf_base64decode(base64_buf, base64_size, base64_decode_buffer.data,
-        sizeof(base64_decode_buffer.data), &base64_decode_buffer.len) != 0)
+        base64_decode_buffer.decode_blen, &base64_decode_buffer.len) != 0)
         return NO_MATCH;
 
     return MATCH;
@@ -287,7 +287,7 @@ IpsOption::EvalStatus Base64DataOption::eval(Cursor& c, Packet* p)
 {
     // cppcheck-suppress unreadVariable
     RuleProfile profile(base64PerfStats);
-    const DataBuffer& base64_decode_buffer = DetectionEngine::get_alt_buffer(p);
+    const DataPointer& base64_decode_buffer = DetectionEngine::get_alt_buffer(p);
 
     if ( !base64_decode_buffer.len )
         return NO_MATCH;
index a1f473a61036cb790ba1a7ff2d8eaaed1411a699..40d98457a62a87d810eb9a0a356aa2f4974b8f71 100644 (file)
@@ -384,7 +384,7 @@ void FastLogger::log_data(Packet* p, const Event& event)
     else if ( log_pkt )
         ObfuscateLogNetData(fast_log, p->data, p->dsize, p, nullptr, "pkt_data", ins_name);
 
-    DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
+    const DataPointer& buf = DetectionEngine::get_alt_buffer(p);
 
     if ( buf.len and event.sig_info->gid != 116 )
         LogNetData(fast_log, buf.data, buf.len, p, "alt");
index be2b6b901f020f219ba03ba7c9f799ee863ef28d..c58a956eac83d59d1cd0f702b3eae710ed1cac39 100644 (file)
@@ -41,7 +41,7 @@ THREAD_LOCAL ProfileStats psPerfStats;
 
 static void make_port_scan_info(Packet* p, PS_PROTO* proto)
 {
-    DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
+    DataBuffer& buf = DetectionEngine::acquire_alt_buffer(p);
 
     SfIp* ip1 = &proto->low_ip;
     SfIp* ip2 = &proto->high_ip;
@@ -59,7 +59,7 @@ static void make_port_scan_info(Packet* p, PS_PROTO* proto)
     else
         type = 'r';
 
-    buf.len = safe_snprintf((char*)buf.data, sizeof(buf.data),
+    buf.len = safe_snprintf((char*)buf.data, buf.decode_blen,
         "Priority Count: %d\n"
         "Connection Count: %d\n"
         "IP Count: %d\n"
@@ -76,13 +76,13 @@ static void make_port_scan_info(Packet* p, PS_PROTO* proto)
 
 static void make_open_port_info(Packet* p, PS_PROTO* proto)
 {
-    DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
+    DataBuffer& buf = DetectionEngine::acquire_alt_buffer(p);
 
     SfIp* ip1 = &proto->low_ip;
     char a1[INET6_ADDRSTRLEN];
     ip1->ntop(a1, sizeof(a1));
 
-    buf.len += safe_snprintf((char*)buf.data+buf.len, sizeof(buf.data)-buf.len,
+    buf.len += safe_snprintf((char*)buf.data + buf.len, buf.decode_blen - buf.len,
         "Scanned IP: %s\n"
         "Port Count: %d\n"
         "Open Ports:",
@@ -92,20 +92,20 @@ static void make_open_port_info(Packet* p, PS_PROTO* proto)
     for ( int i = 0; i < proto->open_ports_cnt; i++ )
     {
         buf.len += safe_snprintf(
-            (char*)buf.data + buf.len, sizeof(buf.data) - buf.len, " %hu", proto->open_ports[i]);
+            (char*)buf.data + buf.len, buf.decode_blen - buf.len, " %hu", proto->open_ports[i]);
     }
-    buf.len += safe_snprintf((char*)buf.data + buf.len, sizeof(buf.data) - buf.len, "\n");
+    buf.len += safe_snprintf((char*)buf.data + buf.len, buf.decode_blen - buf.len, "\n");
 }
 
 #if 0
 // FIXIT-L add open port for port sweeps
 static void make_open_port_info(Packet* p, uint16_t port)
 {
-    DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
+    DataBuffer& buf = DetectionEngine::acquire_alt_buffer(p);
 
     SfIpString ip_str;
 
-    buf.len = safe_snprintf((char*)buf.data, sizeof(buf.data),
+    buf.len = safe_snprintf((char*)buf.data, buf.decode_blen,
         "Scanned IP: %s\n"
         "Open Port: %hu\n",
         p->ptrs.ip_api.get_src()->ntop(ip_str), port);
index 8cf063a45509f20721b214eebb8ba85b0be22fb6..2c1208a1992ea9a7a5af262fdac08068b1f9669a 100644 (file)
@@ -930,7 +930,7 @@ int initialize_ftp(FTP_SESSION* session, Packet* p, int iMode)
             (iMode == FTPP_SI_SERVER_MODE && session->server_conf->ignore_telnet_erase_cmds))
             ignoreTelnetErase = FTPP_IGNORE_TNC_ERASE_CMDS;
 
-        DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
+        DataBuffer& buf = DetectionEngine::acquire_alt_buffer(p);
 
         iRet = normalize_telnet(nullptr, p, buf, iMode, ignoreTelnetErase, true);
 
@@ -1361,7 +1361,7 @@ int check_ftp(FTP_SESSION* ftpssn, Packet* p, int iMode)
 
     const unsigned char* end = p->data + p->dsize;
 
-    const DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
+    const DataPointer& buf = DetectionEngine::get_alt_buffer(p);
     if ( buf.len )
         end = buf.data + buf.len;
 
index 4ed8b27e1370ad1dc5cd94d845c0c4d8fce17393..f3b118daba9e2df39284dc2c6992d3247b4d0c8a 100644 (file)
@@ -54,7 +54,7 @@ using namespace snort;
 
 void reset_telnet_buffer(Packet* p)
 {
-    DetectionEngine::get_alt_buffer(p).len = 0;
+    DetectionEngine::reset_alt_buffer(p);
 }
 
 int normalize_telnet(
@@ -160,7 +160,7 @@ int normalize_telnet(
 
     /* walk thru the remainder of the packet */
     while ((read_ptr < end) &&
-        (write_ptr < ((unsigned char*)buf.data) + sizeof(buf.data)))
+        (write_ptr < ((unsigned char*)buf.data) + buf.decode_blen))
     {
         /* if the following byte isn't a subnegotiation initialization */
         if (((read_ptr + 1) < end) &&
index d9b708ffe54017c837745c86820d40840f9cf521..235a7a6f1bdb90fa6070f9ca6d58f1864f6ac456 100644 (file)
@@ -82,7 +82,7 @@ static int SnortTelnet(TELNET_PROTO_CONF* telnet_config, TELNET_SESSION* Telnets
 
     if ( telnet_config->normalize )
     {
-        DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
+        DataBuffer& buf = DetectionEngine::acquire_alt_buffer(p);
         int ret = normalize_telnet(Telnetsession, p, buf, iInspectMode,
             FTPP_APPLY_TNC_ERASE_CMDS, false);
 
index d89c789ab04b62e2b7c2a4936932854db0d98711..0ced92ebc02821a35935af074773c26c411e480c 100644 (file)
@@ -331,12 +331,12 @@ static RpcStatus RpcStatefulInspection(RpcSsnData* rsdata, Packet* p)
 
 static RpcStatus RpcPrepRaw(const uint8_t* data, uint32_t fraglen, Packet* p)
 {
-    DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
+    DataBuffer& buf = DetectionEngine::acquire_alt_buffer(p);
 
-    if (RPC_FRAG_HDR_SIZE + fraglen > sizeof(buf.data))
+    if (RPC_FRAG_HDR_SIZE + fraglen > buf.decode_blen)
         return RPC_STATUS__ERROR;
 
-    memcpy_s(buf.data, sizeof(buf.data), data, RPC_FRAG_HDR_SIZE + fraglen);
+    memcpy_s(buf.data, buf.decode_blen, data, RPC_FRAG_HDR_SIZE + fraglen);
     buf.len = (RPC_FRAG_HDR_SIZE + fraglen);
 
     return RPC_STATUS__SUCCESS;
@@ -344,7 +344,7 @@ static RpcStatus RpcPrepRaw(const uint8_t* data, uint32_t fraglen, Packet* p)
 
 static RpcStatus RpcPrepFrag(RpcSsnData* rsdata, Packet* p)
 {
-    DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
+    DataBuffer& buf = DetectionEngine::acquire_alt_buffer(p);
     uint32_t fraghdr = htonl(RpcBufLen(&rsdata->frag));
 
     buf.data[0] = *((uint8_t*)&fraghdr);
@@ -354,13 +354,13 @@ static RpcStatus RpcPrepFrag(RpcSsnData* rsdata, Packet* p)
 
     buf.data[0] |= 0x80;
 
-    if (RpcBufLen(&rsdata->frag) > sizeof(buf.data) - 4)
+    if (RpcBufLen(&rsdata->frag) > buf.decode_blen - 4)
     {
         RpcBufClean(&rsdata->frag);
         return RPC_STATUS__ERROR;
     }
 
-    memcpy_s(buf.data + 4, sizeof(buf.data) - 4,
+    memcpy_s(buf.data + 4, buf.decode_blen - 4,
         RpcBufData(&rsdata->frag), RpcBufLen(&rsdata->frag));
 
     if (RpcBufLen(&rsdata->frag) > RPC_MAX_BUF_SIZE)
@@ -373,14 +373,14 @@ static RpcStatus RpcPrepFrag(RpcSsnData* rsdata, Packet* p)
 
 static RpcStatus RpcPrepSeg(RpcSsnData* rsdata, Packet* p)
 {
-    DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
+    DataBuffer& buf = DetectionEngine::acquire_alt_buffer(p);
 
-    if (RpcBufLen(&rsdata->seg) > sizeof(buf.data))
+    if (RpcBufLen(&rsdata->seg) > buf.decode_blen)
     {
         RpcBufClean(&rsdata->seg);
         return RPC_STATUS__ERROR;
     }
-    memcpy_s(buf.data, sizeof(buf.data),
+    memcpy_s(buf.data, buf.decode_blen,
         RpcBufData(&rsdata->seg), RpcBufLen(&rsdata->seg));
 
     if (RpcBufLen(&rsdata->seg) > RPC_MAX_BUF_SIZE)
@@ -603,8 +603,8 @@ static int ConvertRPC(RpcSsnData* rsdata, Packet* p)
     uint32_t fraghdr;   /* Used to store the RPC fragment header data */
     int fragcount = 0;   /* How many fragment counters have we seen? */
 
-    DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
-    size_t decode_buf_rem = sizeof(buf.data);
+    DataBuffer& buf = DetectionEngine::acquire_alt_buffer(p);
+    size_t decode_buf_rem = buf.decode_blen;
 
     if (psize < MIN_CALL_BODY_SZ)
     {
@@ -824,8 +824,7 @@ void RpcDecode::eval(Packet* p)
 
 void RpcDecode::clear(Packet* p)
 {
-    DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
-    buf.len = 0;
+    DetectionEngine::reset_alt_buffer(p);
 }
 
 //-------------------------------------------------------------------------
index 6a59f29744e416afa92afbd9e738a36363ef4691..63265e804c6329a1085b95b11a56600233fe6841 100644 (file)
@@ -75,13 +75,12 @@ SMTPEol SMTP_GetEOL(const uint8_t* ptr, const uint8_t* end,
 
 void SMTP_ResetAltBuffer(Packet* p)
 {
-    DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
-    buf.len = 0;
+    DetectionEngine::reset_alt_buffer(p);
 }
 
 const uint8_t* SMTP_GetAltBuffer(Packet* p, unsigned& len)
 {
-    const DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
+    const DataPointer& buf = DetectionEngine::get_alt_buffer(p);
     len = buf.len;
     return len ? buf.data : nullptr;
 }
@@ -96,8 +95,8 @@ int SMTP_CopyToAltBuffer(Packet* p, const uint8_t* start, int length)
     if (length == 0)
         return 0;
 
-    DataBuffer& buf = DetectionEngine::get_alt_buffer(p);
-    unsigned alt_size = sizeof(buf.data);
+    DataBuffer& buf = DetectionEngine::acquire_alt_buffer(p);
+    unsigned alt_size = buf.decode_blen;
 
     if ((unsigned long)length > alt_size - buf.len)
     {