From: Yehor Velykozhon -X (yvelykoz - SOFTSERVE INC at Cisco) Date: Mon, 12 Feb 2024 13:45:05 +0000 (+0000) Subject: Pull request #4114: ips_context alt_buffer update X-Git-Tag: 3.1.81.0~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=df5daae6154ca5e4339e2c4bdff540d4e3fbb578;p=thirdparty%2Fsnort3.git Pull request #4114: ips_context alt_buffer update Merge in SNORT/snort3 from ~YVELYKOZ/snort3:ips_context_allocation_upd to master Squashed commit of the following: commit ee31592668aae0a799f3a54298eb594ca94698fd Author: Yehor Velykozhon Date: Tue Nov 21 14:59:36 2023 +0200 ips_context: add lazy-allocation of alt buffer --- diff --git a/src/detection/detection_engine.cc b/src/detection/detection_engine.cc index e659b7701..771f6b4d8 100644 --- a/src/detection/detection_engine.cc +++ b/src/detection/detection_engine.cc @@ -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(); diff --git a/src/detection/detection_engine.h b/src/detection/detection_engine.h index dd73347ca..e86fc7c8b 100644 --- a/src/detection/detection_engine.h +++ b/src/detection/detection_engine.h @@ -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 }; diff --git a/src/detection/detection_util.h b/src/detection/detection_util.h index 0f583100c..7c44adef2 100644 --- a/src/detection/detection_util.h +++ b/src/detection/detection_util.h @@ -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 + #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(data) = new uint8_t[DECODE_BLEN]; + } + + uint8_t* const data = nullptr; + unsigned len = 0; }; struct MatchedBuffer diff --git a/src/detection/fp_detect.cc b/src/detection/fp_detect.cc index c9e97556d..df3c3c611 100644 --- a/src/detection/fp_detect.cc +++ b/src/detection/fp_detect.cc @@ -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 ) { diff --git a/src/framework/cursor.cc b/src/framework/cursor.cc index 74adb2f17..5a280fdc2 100644 --- a/src/framework/cursor.cc +++ b/src/framework/cursor.cc @@ -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); diff --git a/src/ips_options/ips_base64.cc b/src/ips_options/ips_base64.cc index b2f13147b..6b56627cb 100644 --- a/src/ips_options/ips_base64.cc +++ b/src/ips_options/ips_base64.cc @@ -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; diff --git a/src/loggers/alert_fast.cc b/src/loggers/alert_fast.cc index a1f473a61..40d98457a 100644 --- a/src/loggers/alert_fast.cc +++ b/src/loggers/alert_fast.cc @@ -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"); diff --git a/src/network_inspectors/port_scan/port_scan.cc b/src/network_inspectors/port_scan/port_scan.cc index be2b6b901..c58a956ea 100644 --- a/src/network_inspectors/port_scan/port_scan.cc +++ b/src/network_inspectors/port_scan/port_scan.cc @@ -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); diff --git a/src/service_inspectors/ftp_telnet/pp_ftp.cc b/src/service_inspectors/ftp_telnet/pp_ftp.cc index 8cf063a45..2c1208a19 100644 --- a/src/service_inspectors/ftp_telnet/pp_ftp.cc +++ b/src/service_inspectors/ftp_telnet/pp_ftp.cc @@ -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; diff --git a/src/service_inspectors/ftp_telnet/pp_telnet.cc b/src/service_inspectors/ftp_telnet/pp_telnet.cc index 4ed8b27e1..f3b118dab 100644 --- a/src/service_inspectors/ftp_telnet/pp_telnet.cc +++ b/src/service_inspectors/ftp_telnet/pp_telnet.cc @@ -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) && diff --git a/src/service_inspectors/ftp_telnet/telnet.cc b/src/service_inspectors/ftp_telnet/telnet.cc index d9b708ffe..235a7a6f1 100644 --- a/src/service_inspectors/ftp_telnet/telnet.cc +++ b/src/service_inspectors/ftp_telnet/telnet.cc @@ -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); diff --git a/src/service_inspectors/rpc_decode/rpc_decode.cc b/src/service_inspectors/rpc_decode/rpc_decode.cc index d89c789ab..0ced92ebc 100644 --- a/src/service_inspectors/rpc_decode/rpc_decode.cc +++ b/src/service_inspectors/rpc_decode/rpc_decode.cc @@ -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); } //------------------------------------------------------------------------- diff --git a/src/service_inspectors/smtp/smtp_util.cc b/src/service_inspectors/smtp/smtp_util.cc index 6a59f2974..63265e804 100644 --- a/src/service_inspectors/smtp/smtp_util.cc +++ b/src/service_inspectors/smtp/smtp_util.cc @@ -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) {