From fd7bd9c200e67b4038223ab73603e2b3871ce4e2 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Fri, 2 May 2025 15:59:44 +0200 Subject: [PATCH] src: new file detect-engine-inspect-buffer.h For InspectionBuffer structure and related functions Bindgen it for rust, especially transforms Ticket: 7667 --- rust/src/detect/transforms/casechange.rs | 23 +- .../detect/transforms/compress_whitespace.rs | 15 +- rust/src/detect/transforms/domain.rs | 23 +- rust/src/detect/transforms/dotprefix.rs | 15 +- rust/src/detect/transforms/hash.rs | 31 +-- rust/src/detect/transforms/http_headers.rs | 23 +- rust/src/detect/transforms/mod.rs | 11 - .../src/detect/transforms/strip_whitespace.rs | 15 +- rust/src/detect/transforms/urldecode.rs | 15 +- rust/src/detect/transforms/xor.rs | 15 +- rust/sys/src/sys.rs | 39 ++- src/Makefile.am | 2 + src/bindgen.h | 3 + src/detect-engine-helper.c | 10 - src/detect-engine-helper.h | 4 +- src/detect-engine-inspect-buffer.c | 257 ++++++++++++++++++ src/detect-engine-inspect-buffer.h | 76 ++++++ src/detect-engine.c | 234 ---------------- src/detect-engine.h | 20 -- src/detect.h | 25 +- src/util-file-decompression.c | 2 +- 21 files changed, 446 insertions(+), 412 deletions(-) create mode 100644 src/detect-engine-inspect-buffer.c create mode 100644 src/detect-engine-inspect-buffer.h diff --git a/rust/src/detect/transforms/casechange.rs b/rust/src/detect/transforms/casechange.rs index b9a7356fbc..cea9d9248e 100644 --- a/rust/src/detect/transforms/casechange.rs +++ b/rust/src/detect/transforms/casechange.rs @@ -15,14 +15,11 @@ * 02110-1301, USA. */ -use super::{ - InspectionBufferCheckAndExpand, InspectionBufferLength, InspectionBufferPtr, - InspectionBufferTruncate, -}; use crate::detect::SIGMATCH_NOOPT; use suricata_sys::sys::{ DetectEngineCtx, DetectEngineThreadCtx, InspectionBuffer, SCDetectHelperTransformRegister, - SCDetectSignatureAddTransform, SCTransformTableElmt, Signature, + SCDetectSignatureAddTransform, SCInspectionBufferCheckAndExpand, SCInspectionBufferTruncate, + SCTransformTableElmt, Signature, }; use std::os::raw::{c_int, c_void}; @@ -46,14 +43,14 @@ fn tolower_transform_do(input: &[u8], output: &mut [u8]) { unsafe extern "C" fn tolower_transform( _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void, ) { - let input = InspectionBufferPtr(buffer); - let input_len = InspectionBufferLength(buffer); + let input = (*buffer).inspect; + let input_len = (*buffer).inspect_len; if input.is_null() || input_len == 0 { return; } let input = build_slice!(input, input_len as usize); - let output = InspectionBufferCheckAndExpand(buffer, input_len); + let output = SCInspectionBufferCheckAndExpand(buffer, input_len); if output.is_null() { // allocation failure return; @@ -62,7 +59,7 @@ unsafe extern "C" fn tolower_transform( tolower_transform_do(input, output); - InspectionBufferTruncate(buffer, input_len); + SCInspectionBufferTruncate(buffer, input_len); } unsafe extern "C" fn tolower_validate(content: *const u8, len: u16, _ctx: *mut c_void) -> bool { @@ -108,14 +105,14 @@ fn toupper_transform_do(input: &[u8], output: &mut [u8]) { unsafe extern "C" fn toupper_transform( _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void, ) { - let input = InspectionBufferPtr(buffer); - let input_len = InspectionBufferLength(buffer); + let input = (*buffer).inspect; + let input_len = (*buffer).inspect_len; if input.is_null() || input_len == 0 { return; } let input = build_slice!(input, input_len as usize); - let output = InspectionBufferCheckAndExpand(buffer, input_len); + let output = SCInspectionBufferCheckAndExpand(buffer, input_len); if output.is_null() { // allocation failure return; @@ -124,7 +121,7 @@ unsafe extern "C" fn toupper_transform( toupper_transform_do(input, output); - InspectionBufferTruncate(buffer, input_len); + SCInspectionBufferTruncate(buffer, input_len); } unsafe extern "C" fn toupper_validate(content: *const u8, len: u16, _ctx: *mut c_void) -> bool { diff --git a/rust/src/detect/transforms/compress_whitespace.rs b/rust/src/detect/transforms/compress_whitespace.rs index 25eab6283e..7d33825614 100644 --- a/rust/src/detect/transforms/compress_whitespace.rs +++ b/rust/src/detect/transforms/compress_whitespace.rs @@ -15,14 +15,11 @@ * 02110-1301, USA. */ -use super::{ - InspectionBufferCheckAndExpand, InspectionBufferLength, InspectionBufferPtr, - InspectionBufferTruncate, -}; use crate::detect::SIGMATCH_NOOPT; use suricata_sys::sys::{ DetectEngineCtx, DetectEngineThreadCtx, InspectionBuffer, SCDetectHelperTransformRegister, - SCDetectSignatureAddTransform, SCTransformTableElmt, Signature, + SCDetectSignatureAddTransform, SCInspectionBufferCheckAndExpand, SCInspectionBufferTruncate, + SCTransformTableElmt, Signature, }; use std::os::raw::{c_int, c_void}; @@ -56,14 +53,14 @@ fn compress_whitespace_transform_do(input: &[u8], output: &mut [u8]) -> u32 { unsafe extern "C" fn compress_whitespace_transform( _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void, ) { - let input = InspectionBufferPtr(buffer); - let input_len = InspectionBufferLength(buffer); + let input = (*buffer).inspect; + let input_len = (*buffer).inspect_len; if input.is_null() || input_len == 0 { return; } let input = build_slice!(input, input_len as usize); - let output = InspectionBufferCheckAndExpand(buffer, input_len); + let output = SCInspectionBufferCheckAndExpand(buffer, input_len); if output.is_null() { // allocation failure return; @@ -72,7 +69,7 @@ unsafe extern "C" fn compress_whitespace_transform( let output_len = compress_whitespace_transform_do(input, output); - InspectionBufferTruncate(buffer, output_len); + SCInspectionBufferTruncate(buffer, output_len); } fn compress_whitespace_validate_do(input: &[u8]) -> bool { diff --git a/rust/src/detect/transforms/domain.rs b/rust/src/detect/transforms/domain.rs index eeb3595c80..709c9d3ee6 100644 --- a/rust/src/detect/transforms/domain.rs +++ b/rust/src/detect/transforms/domain.rs @@ -15,14 +15,11 @@ * 02110-1301, USA. */ -use super::{ - InspectionBufferCheckAndExpand, InspectionBufferLength, InspectionBufferPtr, - InspectionBufferTruncate, -}; use crate::detect::SIGMATCH_NOOPT; use suricata_sys::sys::{ DetectEngineCtx, DetectEngineThreadCtx, InspectionBuffer, SCDetectHelperTransformRegister, - SCDetectSignatureAddTransform, SCTransformTableElmt, Signature, + SCDetectSignatureAddTransform, SCTransformTableElmt, Signature, SCInspectionBufferCheckAndExpand, + SCInspectionBufferTruncate, }; use std::os::raw::{c_int, c_void}; @@ -50,14 +47,14 @@ fn get_domain(input: &[u8], output: &mut [u8]) -> u32 { unsafe extern "C" fn domain_transform( _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void, ) { - let input = InspectionBufferPtr(buffer); - let input_len = InspectionBufferLength(buffer); + let input = (*buffer).inspect; + let input_len = (*buffer).inspect_len; if input.is_null() || input_len == 0 { return; } let input = build_slice!(input, input_len as usize); - let output = InspectionBufferCheckAndExpand(buffer, input_len); + let output = SCInspectionBufferCheckAndExpand(buffer, input_len); if output.is_null() { // allocation failure return; @@ -66,7 +63,7 @@ unsafe extern "C" fn domain_transform( let output_len = get_domain(input, output); - InspectionBufferTruncate(buffer, output_len); + SCInspectionBufferTruncate(buffer, output_len); } unsafe extern "C" fn tld_setup( @@ -89,14 +86,14 @@ fn get_tld(input: &[u8], output: &mut [u8]) -> u32 { unsafe extern "C" fn tld_transform( _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void, ) { - let input = InspectionBufferPtr(buffer); - let input_len = InspectionBufferLength(buffer); + let input = (*buffer).inspect; + let input_len = (*buffer).inspect_len; if input.is_null() || input_len == 0 { return; } let input = build_slice!(input, input_len as usize); - let output = InspectionBufferCheckAndExpand(buffer, input_len); + let output = SCInspectionBufferCheckAndExpand(buffer, input_len); if output.is_null() { // allocation failure return; @@ -105,7 +102,7 @@ unsafe extern "C" fn tld_transform( let output_len = get_tld(input, output); - InspectionBufferTruncate(buffer, output_len); + SCInspectionBufferTruncate(buffer, output_len); } #[no_mangle] diff --git a/rust/src/detect/transforms/dotprefix.rs b/rust/src/detect/transforms/dotprefix.rs index 141a19fe2b..ac2693cbfe 100644 --- a/rust/src/detect/transforms/dotprefix.rs +++ b/rust/src/detect/transforms/dotprefix.rs @@ -15,14 +15,11 @@ * 02110-1301, USA. */ -use super::{ - InspectionBufferCheckAndExpand, InspectionBufferLength, InspectionBufferPtr, - InspectionBufferTruncate, -}; use crate::detect::SIGMATCH_NOOPT; use suricata_sys::sys::{ DetectEngineCtx, DetectEngineThreadCtx, InspectionBuffer, SCDetectHelperTransformRegister, - SCDetectSignatureAddTransform, SCTransformTableElmt, Signature, + SCDetectSignatureAddTransform, SCTransformTableElmt, Signature, SCInspectionBufferCheckAndExpand, + SCInspectionBufferTruncate, }; use std::os::raw::{c_int, c_void}; @@ -48,17 +45,17 @@ fn dot_prefix_transform_do(input: &[u8], output: &mut [u8]) { unsafe extern "C" fn dot_prefix_transform( _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void, ) { - let input_len = InspectionBufferLength(buffer); + let input_len = (*buffer).inspect_len; if input_len == 0 { return; } - let output = InspectionBufferCheckAndExpand(buffer, input_len + 1); + let output = SCInspectionBufferCheckAndExpand(buffer, input_len + 1); if output.is_null() { // allocation failure return; } // get input after possible realloc - let input = InspectionBufferPtr(buffer); + let input = (*buffer).inspect; if input.is_null() { // allocation failure return; @@ -68,7 +65,7 @@ unsafe extern "C" fn dot_prefix_transform( dot_prefix_transform_do(input, output); - InspectionBufferTruncate(buffer, input_len + 1); + SCInspectionBufferTruncate(buffer, input_len + 1); } #[no_mangle] diff --git a/rust/src/detect/transforms/hash.rs b/rust/src/detect/transforms/hash.rs index 913fe7e4b3..7a4a27f974 100644 --- a/rust/src/detect/transforms/hash.rs +++ b/rust/src/detect/transforms/hash.rs @@ -15,14 +15,11 @@ * 02110-1301, USA. */ -use super::{ - InspectionBufferCheckAndExpand, InspectionBufferLength, InspectionBufferPtr, - InspectionBufferTruncate, -}; use crate::detect::SIGMATCH_NOOPT; use suricata_sys::sys::{ DetectEngineCtx, DetectEngineThreadCtx, InspectionBuffer, SCDetectHelperTransformRegister, - SCDetectSignatureAddTransform, SCTransformTableElmt, Signature, + SCDetectSignatureAddTransform, SCTransformTableElmt, Signature, SCInspectionBufferCheckAndExpand, + SCInspectionBufferTruncate, }; use crate::ffi::hashing::{G_DISABLE_HASHING, SC_SHA1_LEN, SC_SHA256_LEN}; @@ -57,14 +54,14 @@ fn md5_transform_do(input: &[u8], output: &mut [u8]) { unsafe extern "C" fn md5_transform( _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void, ) { - let input = InspectionBufferPtr(buffer); - let input_len = InspectionBufferLength(buffer); + let input = (*buffer).inspect; + let input_len = (*buffer).inspect_len; if input.is_null() || input_len == 0 { return; } let input = build_slice!(input, input_len as usize); - let output = InspectionBufferCheckAndExpand(buffer, SC_MD5_LEN as u32); + let output = SCInspectionBufferCheckAndExpand(buffer, SC_MD5_LEN as u32); if output.is_null() { // allocation failure return; @@ -73,7 +70,7 @@ unsafe extern "C" fn md5_transform( md5_transform_do(input, output); - InspectionBufferTruncate(buffer, SC_MD5_LEN as u32); + SCInspectionBufferTruncate(buffer, SC_MD5_LEN as u32); } #[no_mangle] @@ -111,14 +108,14 @@ fn sha1_transform_do(input: &[u8], output: &mut [u8]) { unsafe extern "C" fn sha1_transform( _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void, ) { - let input = InspectionBufferPtr(buffer); - let input_len = InspectionBufferLength(buffer); + let input = (*buffer).inspect; + let input_len = (*buffer).inspect_len; if input.is_null() || input_len == 0 { return; } let input = build_slice!(input, input_len as usize); - let output = InspectionBufferCheckAndExpand(buffer, SC_SHA1_LEN as u32); + let output = SCInspectionBufferCheckAndExpand(buffer, SC_SHA1_LEN as u32); if output.is_null() { // allocation failure return; @@ -127,7 +124,7 @@ unsafe extern "C" fn sha1_transform( sha1_transform_do(input, output); - InspectionBufferTruncate(buffer, SC_SHA1_LEN as u32); + SCInspectionBufferTruncate(buffer, SC_SHA1_LEN as u32); } #[no_mangle] @@ -165,14 +162,14 @@ fn sha256_transform_do(input: &[u8], output: &mut [u8]) { unsafe extern "C" fn sha256_transform( _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void, ) { - let input = InspectionBufferPtr(buffer); - let input_len = InspectionBufferLength(buffer); + let input = (*buffer).inspect; + let input_len = (*buffer).inspect_len; if input.is_null() || input_len == 0 { return; } let input = build_slice!(input, input_len as usize); - let output = InspectionBufferCheckAndExpand(buffer, SC_SHA256_LEN as u32); + let output = SCInspectionBufferCheckAndExpand(buffer, SC_SHA256_LEN as u32); if output.is_null() { // allocation failure return; @@ -181,7 +178,7 @@ unsafe extern "C" fn sha256_transform( sha256_transform_do(input, output); - InspectionBufferTruncate(buffer, SC_SHA256_LEN as u32); + SCInspectionBufferTruncate(buffer, SC_SHA256_LEN as u32); } #[no_mangle] diff --git a/rust/src/detect/transforms/http_headers.rs b/rust/src/detect/transforms/http_headers.rs index 49366c1d70..7bd9495038 100644 --- a/rust/src/detect/transforms/http_headers.rs +++ b/rust/src/detect/transforms/http_headers.rs @@ -15,14 +15,11 @@ * 02110-1301, USA. */ -use super::{ - InspectionBufferCheckAndExpand, InspectionBufferLength, InspectionBufferPtr, - InspectionBufferTruncate, -}; use crate::detect::SIGMATCH_NOOPT; use suricata_sys::sys::{ DetectEngineCtx, DetectEngineThreadCtx, InspectionBuffer, SCDetectHelperTransformRegister, - SCDetectSignatureAddTransform, SCTransformTableElmt, Signature, + SCDetectSignatureAddTransform, SCInspectionBufferCheckAndExpand, SCInspectionBufferTruncate, + SCTransformTableElmt, Signature, }; use std::os::raw::{c_int, c_void}; @@ -59,14 +56,14 @@ fn header_lowertransform_do(input: &[u8], output: &mut [u8]) { unsafe extern "C" fn header_lowertransform( _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void, ) { - let input = InspectionBufferPtr(buffer); - let input_len = InspectionBufferLength(buffer); + let input = (*buffer).inspect; + let input_len = (*buffer).inspect_len; if input.is_null() || input_len == 0 { return; } let input = build_slice!(input, input_len as usize); - let output = InspectionBufferCheckAndExpand(buffer, input_len); + let output = SCInspectionBufferCheckAndExpand(buffer, input_len); if output.is_null() { // allocation failure return; @@ -75,7 +72,7 @@ unsafe extern "C" fn header_lowertransform( header_lowertransform_do(input, output); - InspectionBufferTruncate(buffer, input_len); + SCInspectionBufferTruncate(buffer, input_len); } #[no_mangle] @@ -123,14 +120,14 @@ fn strip_pseudo_transform_do(input: &[u8], output: &mut [u8]) -> u32 { unsafe extern "C" fn strip_pseudo_transform( _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void, ) { - let input = InspectionBufferPtr(buffer); - let input_len = InspectionBufferLength(buffer); + let input = (*buffer).inspect; + let input_len = (*buffer).inspect_len; if input.is_null() || input_len == 0 { return; } let input = build_slice!(input, input_len as usize); - let output = InspectionBufferCheckAndExpand(buffer, input_len); + let output = SCInspectionBufferCheckAndExpand(buffer, input_len); if output.is_null() { // allocation failure return; @@ -139,7 +136,7 @@ unsafe extern "C" fn strip_pseudo_transform( let out_len = strip_pseudo_transform_do(input, output); - InspectionBufferTruncate(buffer, out_len); + SCInspectionBufferTruncate(buffer, out_len); } #[no_mangle] diff --git a/rust/src/detect/transforms/mod.rs b/rust/src/detect/transforms/mod.rs index bffcfe6642..7dca2abe92 100644 --- a/rust/src/detect/transforms/mod.rs +++ b/rust/src/detect/transforms/mod.rs @@ -17,8 +17,6 @@ //! Module for transforms -use suricata_sys::sys::InspectionBuffer; - pub mod casechange; pub mod compress_whitespace; pub mod domain; @@ -28,12 +26,3 @@ pub mod http_headers; pub mod strip_whitespace; pub mod urldecode; pub mod xor; - -/// cbindgen:ignore -extern "C" { - pub fn InspectionBufferPtr(buf: *const InspectionBuffer) -> *const u8; - pub fn InspectionBufferLength(buf: *const InspectionBuffer) -> u32; - pub fn InspectionBufferCopy(ibuf: *const InspectionBuffer, buf: *const u8, buf_len: u32); - pub fn InspectionBufferCheckAndExpand(ibuf: *const InspectionBuffer, buf_len: u32) -> *mut u8; - pub fn InspectionBufferTruncate(ibuf: *const InspectionBuffer, buf_len: u32); -} diff --git a/rust/src/detect/transforms/strip_whitespace.rs b/rust/src/detect/transforms/strip_whitespace.rs index 9298614abb..dbc77fb531 100644 --- a/rust/src/detect/transforms/strip_whitespace.rs +++ b/rust/src/detect/transforms/strip_whitespace.rs @@ -15,14 +15,11 @@ * 02110-1301, USA. */ -use super::{ - InspectionBufferCheckAndExpand, InspectionBufferLength, InspectionBufferPtr, - InspectionBufferTruncate, -}; use crate::detect::SIGMATCH_NOOPT; use suricata_sys::sys::{ DetectEngineCtx, DetectEngineThreadCtx, InspectionBuffer, SCDetectHelperTransformRegister, - SCDetectSignatureAddTransform, SCTransformTableElmt, Signature, + SCDetectSignatureAddTransform, SCInspectionBufferCheckAndExpand, SCInspectionBufferTruncate, + SCTransformTableElmt, Signature, }; use std::os::raw::{c_int, c_void}; @@ -53,14 +50,14 @@ fn strip_whitespace_transform_do(input: &[u8], output: &mut [u8]) -> u32 { unsafe extern "C" fn strip_whitespace_transform( _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void, ) { - let input = InspectionBufferPtr(buffer); - let input_len = InspectionBufferLength(buffer); + let input = (*buffer).inspect; + let input_len = (*buffer).inspect_len; if input.is_null() || input_len == 0 { return; } let input = build_slice!(input, input_len as usize); - let output = InspectionBufferCheckAndExpand(buffer, input_len); + let output = SCInspectionBufferCheckAndExpand(buffer, input_len); if output.is_null() { // allocation failure return; @@ -69,7 +66,7 @@ unsafe extern "C" fn strip_whitespace_transform( let output_len = strip_whitespace_transform_do(input, output); - InspectionBufferTruncate(buffer, output_len); + SCInspectionBufferTruncate(buffer, output_len); } unsafe extern "C" fn strip_whitespace_validate( diff --git a/rust/src/detect/transforms/urldecode.rs b/rust/src/detect/transforms/urldecode.rs index 0aa46def25..a7317db6b5 100644 --- a/rust/src/detect/transforms/urldecode.rs +++ b/rust/src/detect/transforms/urldecode.rs @@ -15,14 +15,11 @@ * 02110-1301, USA. */ -use super::{ - InspectionBufferCheckAndExpand, InspectionBufferLength, InspectionBufferPtr, - InspectionBufferTruncate, -}; use crate::detect::SIGMATCH_NOOPT; use suricata_sys::sys::{ DetectEngineCtx, DetectEngineThreadCtx, InspectionBuffer, SCDetectHelperTransformRegister, - SCDetectSignatureAddTransform, SCTransformTableElmt, Signature, + SCDetectSignatureAddTransform, SCInspectionBufferCheckAndExpand, SCInspectionBufferTruncate, + SCTransformTableElmt, Signature, }; use std::os::raw::{c_int, c_void}; @@ -93,14 +90,14 @@ fn url_decode_transform_do(input: &[u8], output: &mut [u8]) -> u32 { unsafe extern "C" fn url_decode_transform( _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void, ) { - let input = InspectionBufferPtr(buffer); - let input_len = InspectionBufferLength(buffer); + let input = (*buffer).inspect; + let input_len = (*buffer).inspect_len; if input.is_null() || input_len == 0 { return; } let input = build_slice!(input, input_len as usize); - let output = InspectionBufferCheckAndExpand(buffer, input_len); + let output = SCInspectionBufferCheckAndExpand(buffer, input_len); if output.is_null() { // allocation failure return; @@ -109,7 +106,7 @@ unsafe extern "C" fn url_decode_transform( let out_len = url_decode_transform_do(input, output); - InspectionBufferTruncate(buffer, out_len); + SCInspectionBufferTruncate(buffer, out_len); } #[no_mangle] diff --git a/rust/src/detect/transforms/xor.rs b/rust/src/detect/transforms/xor.rs index fdafea974b..e4f46f2f09 100644 --- a/rust/src/detect/transforms/xor.rs +++ b/rust/src/detect/transforms/xor.rs @@ -15,14 +15,11 @@ * 02110-1301, USA. */ -use super::{ - InspectionBufferCheckAndExpand, InspectionBufferLength, InspectionBufferPtr, - InspectionBufferTruncate, -}; use crate::detect::SIGMATCH_QUOTES_MANDATORY; use suricata_sys::sys::{ DetectEngineCtx, DetectEngineThreadCtx, InspectionBuffer, SCDetectHelperTransformRegister, - SCDetectSignatureAddTransform, SCTransformTableElmt, Signature, + SCDetectSignatureAddTransform, SCInspectionBufferCheckAndExpand, SCInspectionBufferTruncate, + SCTransformTableElmt, Signature, }; use std::ffi::CStr; @@ -87,14 +84,14 @@ fn xor_transform_do(input: &[u8], output: &mut [u8], ctx: &DetectTransformXorDat unsafe extern "C" fn xor_transform( _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, ctx: *mut c_void, ) { - let input = InspectionBufferPtr(buffer); - let input_len = InspectionBufferLength(buffer); + let input = (*buffer).inspect; + let input_len = (*buffer).inspect_len; if input.is_null() || input_len == 0 { return; } let input = build_slice!(input, input_len as usize); - let output = InspectionBufferCheckAndExpand(buffer, input_len); + let output = SCInspectionBufferCheckAndExpand(buffer, input_len); if output.is_null() { // allocation failure return; @@ -104,7 +101,7 @@ unsafe extern "C" fn xor_transform( let ctx = cast_pointer!(ctx, DetectTransformXorData); xor_transform_do(input, output, ctx); - InspectionBufferTruncate(buffer, input_len); + SCInspectionBufferTruncate(buffer, input_len); } unsafe extern "C" fn xor_free(_de: *mut DetectEngineCtx, ctx: *mut c_void) { diff --git a/rust/sys/src/sys.rs b/rust/sys/src/sys.rs index 7622b4d673..9a2d9bb60f 100644 --- a/rust/sys/src/sys.rs +++ b/rust/sys/src/sys.rs @@ -200,27 +200,50 @@ extern "C" { } #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct Flow_ { - _unused: [u8; 0], +pub struct InspectionBuffer { + #[doc = "< active pointer, points either to ::buf or ::orig"] + pub inspect: *const u8, + pub inspect_offset: u64, + #[doc = "< size of active data. See to ::len or ::orig_len"] + pub inspect_len: u32, + #[doc = "< is initialized. ::inspect might be NULL if transform lead to 0 size"] + pub initialized: bool, + #[doc = "< DETECT_CI_FLAGS_* for use with DetectEngineContentInspection"] + pub flags: u8, + #[doc = "< how much is in use"] + pub len: u32, + pub buf: *mut u8, + #[doc = "< size of the memory allocation"] + pub size: u32, + pub orig_len: u32, + pub orig: *const u8, } -pub type Flow = Flow_; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct SigMatchCtx_ { +pub struct DetectEngineThreadCtx_ { _unused: [u8; 0], } -pub type SigMatchCtx = SigMatchCtx_; +pub type DetectEngineThreadCtx = DetectEngineThreadCtx_; +extern "C" { + pub fn SCInspectionBufferCheckAndExpand( + buffer: *mut InspectionBuffer, min_size: u32, + ) -> *mut u8; +} +extern "C" { + pub fn SCInspectionBufferTruncate(buffer: *mut InspectionBuffer, buf_len: u32); +} #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct DetectEngineThreadCtx_ { +pub struct Flow_ { _unused: [u8; 0], } -pub type DetectEngineThreadCtx = DetectEngineThreadCtx_; +pub type Flow = Flow_; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct InspectionBuffer { +pub struct SigMatchCtx_ { _unused: [u8; 0], } +pub type SigMatchCtx = SigMatchCtx_; #[doc = " App-layer light version of SigTableElmt"] #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/src/Makefile.am b/src/Makefile.am index fb96da8940..90ddedd816 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -136,6 +136,7 @@ noinst_HEADERS = \ detect-engine-file.h \ detect-engine-frame.h \ detect-engine-helper.h \ + detect-engine-inspect-buffer.h \ detect-engine-iponly.h \ detect-engine-loader.h \ detect-engine-mpm.h \ @@ -724,6 +725,7 @@ libsuricata_c_a_SOURCES = \ detect-engine-file.c \ detect-engine-frame.c \ detect-engine-helper.c \ + detect-engine-inspect-buffer.c \ detect-engine-iponly.c \ detect-engine-loader.c \ detect-engine-mpm.c \ diff --git a/src/bindgen.h b/src/bindgen.h index 4fea8ee2b8..b563da3b65 100644 --- a/src/bindgen.h +++ b/src/bindgen.h @@ -33,6 +33,9 @@ #include "app-layer-protos.h" #include "suricata-plugin.h" +// do not export struct fields only used for debug validation +// do this after suricata-plugin.h which needs autoconf.h to define SC_PACKAGE_VERSION +#undef DEBUG_VALIDATION #include "output-eve-bindgen.h" #include "detect-engine-register.h" #include "detect-engine-buffer.h" diff --git a/src/detect-engine-helper.c b/src/detect-engine-helper.c index 0b4325488f..ce0d20d8fd 100644 --- a/src/detect-engine-helper.c +++ b/src/detect-engine-helper.c @@ -166,13 +166,3 @@ int SCDetectHelperTransformRegister(const SCTransformTableElmt *kw) return transform_id; } - -const uint8_t *InspectionBufferPtr(InspectionBuffer *buf) -{ - return buf->inspect; -} - -uint32_t InspectionBufferLength(InspectionBuffer *buf) -{ - return buf->inspect_len; -} diff --git a/src/detect-engine-helper.h b/src/detect-engine-helper.h index 714bd19a57..ca75ee1168 100644 --- a/src/detect-engine-helper.h +++ b/src/detect-engine-helper.h @@ -25,6 +25,7 @@ #define SURICATA_DETECT_ENGINE_HELPER_H #include "app-layer-protos.h" +#include "detect-engine-inspect-buffer.h" // type from flow.h with only forward declarations for bindgen typedef struct Flow_ Flow; @@ -34,7 +35,6 @@ typedef struct DetectEngineCtx_ DetectEngineCtx; typedef struct Signature_ Signature; typedef struct SigMatchCtx_ SigMatchCtx; typedef struct DetectEngineThreadCtx_ DetectEngineThreadCtx; -typedef struct InspectionBuffer InspectionBuffer; typedef struct DetectEngineTransforms DetectEngineTransforms; typedef InspectionBuffer *(*InspectionBufferGetDataPtr)(struct DetectEngineThreadCtx_ *det_ctx, const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, @@ -92,7 +92,5 @@ int DetectHelperMultiBufferProgressMpmRegister(const char *name, const char *des uint8_t direction, InspectionMultiBufferGetDataPtr GetData, int progress); int SCDetectHelperTransformRegister(const SCTransformTableElmt *kw); -const uint8_t *InspectionBufferPtr(InspectionBuffer *buf); -uint32_t InspectionBufferLength(InspectionBuffer *buf); #endif /* SURICATA_DETECT_ENGINE_HELPER_H */ diff --git a/src/detect-engine-inspect-buffer.c b/src/detect-engine-inspect-buffer.c new file mode 100644 index 0000000000..b33b7e0f13 --- /dev/null +++ b/src/detect-engine-inspect-buffer.c @@ -0,0 +1,257 @@ +/* Copyright (C) 2025 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * 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 + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Victor Julien + */ + +#include "suricata-common.h" +#include "detect-engine-inspect-buffer.h" +#include "detect.h" + +#include "util-validate.h" + +void InspectionBufferClean(DetectEngineThreadCtx *det_ctx) +{ + /* single buffers */ + for (uint32_t i = 0; i < det_ctx->inspect.to_clear_idx; i++) { + const uint32_t idx = det_ctx->inspect.to_clear_queue[i]; + InspectionBuffer *buffer = &det_ctx->inspect.buffers[idx]; + buffer->inspect = NULL; + buffer->initialized = false; + } + det_ctx->inspect.to_clear_idx = 0; + + /* multi buffers */ + for (uint32_t i = 0; i < det_ctx->multi_inspect.to_clear_idx; i++) { + const uint32_t idx = det_ctx->multi_inspect.to_clear_queue[i]; + InspectionBufferMultipleForList *mbuffer = &det_ctx->multi_inspect.buffers[idx]; + for (uint32_t x = 0; x <= mbuffer->max; x++) { + InspectionBuffer *buffer = &mbuffer->inspection_buffers[x]; + buffer->inspect = NULL; + buffer->initialized = false; + } + mbuffer->init = 0; + mbuffer->max = 0; + } + det_ctx->multi_inspect.to_clear_idx = 0; +} + +InspectionBuffer *InspectionBufferGet(DetectEngineThreadCtx *det_ctx, const int list_id) +{ + return &det_ctx->inspect.buffers[list_id]; +} + +static InspectionBufferMultipleForList *InspectionBufferGetMulti( + DetectEngineThreadCtx *det_ctx, const int list_id) +{ + InspectionBufferMultipleForList *buffer = &det_ctx->multi_inspect.buffers[list_id]; + if (!buffer->init) { + det_ctx->multi_inspect.to_clear_queue[det_ctx->multi_inspect.to_clear_idx++] = list_id; + buffer->init = 1; + } + return buffer; +} + +/** \brief for a InspectionBufferMultipleForList get a InspectionBuffer + * \param fb the multiple buffer array + * \param local_id the index to get a buffer + * \param buffer the inspect buffer or NULL in case of error */ +InspectionBuffer *InspectionBufferMultipleForListGet( + DetectEngineThreadCtx *det_ctx, const int list_id, const uint32_t local_id) +{ + if (unlikely(local_id >= 1024)) { + DetectEngineSetEvent(det_ctx, DETECT_EVENT_TOO_MANY_BUFFERS); + return NULL; + } + + InspectionBufferMultipleForList *fb = InspectionBufferGetMulti(det_ctx, list_id); + + if (local_id >= fb->size) { + uint32_t old_size = fb->size; + uint32_t new_size = local_id + 1; + uint32_t grow_by = new_size - old_size; + SCLogDebug("size is %u, need %u, so growing by %u", old_size, new_size, grow_by); + + SCLogDebug("fb->inspection_buffers %p", fb->inspection_buffers); + void *ptr = SCRealloc(fb->inspection_buffers, (local_id + 1) * sizeof(InspectionBuffer)); + if (ptr == NULL) + return NULL; + + InspectionBuffer *to_zero = (InspectionBuffer *)ptr + old_size; + SCLogDebug("ptr %p to_zero %p", ptr, to_zero); + memset((uint8_t *)to_zero, 0, (grow_by * sizeof(InspectionBuffer))); + fb->inspection_buffers = ptr; + fb->size = new_size; + } + + fb->max = MAX(fb->max, local_id); + InspectionBuffer *buffer = &fb->inspection_buffers[local_id]; + SCLogDebug("using buffer %p", buffer); +#ifdef DEBUG_VALIDATION + buffer->multi = true; +#endif + return buffer; +} + +static inline void InspectionBufferApplyTransformsInternal(DetectEngineThreadCtx *det_ctx, + InspectionBuffer *buffer, const DetectEngineTransforms *transforms) +{ + if (transforms) { + for (int i = 0; i < DETECT_TRANSFORMS_MAX; i++) { + const int id = transforms->transforms[i].transform; + if (id == 0) + break; + BUG_ON(sigmatch_table[id].Transform == NULL); + sigmatch_table[id].Transform(det_ctx, buffer, transforms->transforms[i].options); + SCLogDebug("applied transform %s", sigmatch_table[id].name); + } + } +} + +void InspectionBufferApplyTransforms(DetectEngineThreadCtx *det_ctx, InspectionBuffer *buffer, + const DetectEngineTransforms *transforms) +{ + InspectionBufferApplyTransformsInternal(det_ctx, buffer, transforms); +} + +void InspectionBufferInit(InspectionBuffer *buffer, uint32_t initial_size) +{ + memset(buffer, 0, sizeof(*buffer)); + buffer->buf = SCCalloc(initial_size, sizeof(uint8_t)); + if (buffer->buf != NULL) { + buffer->size = initial_size; + } +} + +/** \brief setup the buffer empty */ +void InspectionBufferSetupMultiEmpty(InspectionBuffer *buffer) +{ +#ifdef DEBUG_VALIDATION + DEBUG_VALIDATE_BUG_ON(buffer->initialized); + DEBUG_VALIDATE_BUG_ON(!buffer->multi); +#endif + buffer->inspect = NULL; + buffer->inspect_len = 0; + buffer->len = 0; + buffer->initialized = true; +} + +/** \brief setup the buffer with our initial data */ +void InspectionBufferSetupMulti(DetectEngineThreadCtx *det_ctx, InspectionBuffer *buffer, + const DetectEngineTransforms *transforms, const uint8_t *data, const uint32_t data_len) +{ +#ifdef DEBUG_VALIDATION + DEBUG_VALIDATE_BUG_ON(!buffer->multi); +#endif + buffer->inspect = buffer->orig = data; + buffer->inspect_len = buffer->orig_len = data_len; + buffer->len = 0; + buffer->initialized = true; + + InspectionBufferApplyTransformsInternal(det_ctx, buffer, transforms); +} + +static inline void InspectionBufferSetupInternal(DetectEngineThreadCtx *det_ctx, const int list_id, + InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len) +{ +#ifdef DEBUG_VALIDATION + DEBUG_VALIDATE_BUG_ON(buffer->multi); + DEBUG_VALIDATE_BUG_ON(buffer != InspectionBufferGet(det_ctx, list_id)); +#endif + if (buffer->inspect == NULL) { +#ifdef UNITTESTS + if (det_ctx && list_id != -1) +#endif + det_ctx->inspect.to_clear_queue[det_ctx->inspect.to_clear_idx++] = list_id; + } + buffer->inspect = buffer->orig = data; + buffer->inspect_len = buffer->orig_len = data_len; + buffer->len = 0; + buffer->initialized = true; +} +/** \brief setup the buffer with our initial data */ +void InspectionBufferSetup(DetectEngineThreadCtx *det_ctx, const int list_id, + InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len) +{ + InspectionBufferSetupInternal(det_ctx, list_id, buffer, data, data_len); +} + +/** \brief setup the buffer with our initial data */ +void InspectionBufferSetupAndApplyTransforms(DetectEngineThreadCtx *det_ctx, const int list_id, + InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len, + const DetectEngineTransforms *transforms) +{ + InspectionBufferSetupInternal(det_ctx, list_id, buffer, data, data_len); + InspectionBufferApplyTransformsInternal(det_ctx, buffer, transforms); +} + +void InspectionBufferFree(InspectionBuffer *buffer) +{ + if (buffer->buf != NULL) { + SCFree(buffer->buf); + } + memset(buffer, 0, sizeof(*buffer)); +} + +/** + * \brief make sure that the buffer has at least 'min_size' bytes + * Expand the buffer if necessary + */ +uint8_t *SCInspectionBufferCheckAndExpand(InspectionBuffer *buffer, uint32_t min_size) +{ + if (likely(buffer->size >= min_size)) + return buffer->buf; + + uint32_t new_size = (buffer->size == 0) ? 4096 : buffer->size; + while (new_size < min_size) { + new_size *= 2; + } + + void *ptr = SCRealloc(buffer->buf, new_size); + if (ptr != NULL) { + buffer->buf = ptr; + buffer->size = new_size; + } else { + return NULL; + } + return buffer->buf; +} + +void SCInspectionBufferTruncate(InspectionBuffer *buffer, uint32_t buf_len) +{ + DEBUG_VALIDATE_BUG_ON(buffer->buf == NULL); + DEBUG_VALIDATE_BUG_ON(buf_len > buffer->size); + buffer->inspect = buffer->buf; + buffer->inspect_len = buf_len; + buffer->initialized = true; +} + +void InspectionBufferCopy(InspectionBuffer *buffer, uint8_t *buf, uint32_t buf_len) +{ + SCInspectionBufferCheckAndExpand(buffer, buf_len); + + if (buffer->size) { + uint32_t copy_size = MIN(buf_len, buffer->size); + memcpy(buffer->buf, buf, copy_size); + buffer->inspect = buffer->buf; + buffer->inspect_len = copy_size; + buffer->initialized = true; + } +} diff --git a/src/detect-engine-inspect-buffer.h b/src/detect-engine-inspect-buffer.h new file mode 100644 index 0000000000..a0a704403b --- /dev/null +++ b/src/detect-engine-inspect-buffer.h @@ -0,0 +1,76 @@ +/* Copyright (C) 2025 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * 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 + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Victor Julien + */ + +#ifndef SURICATA_DETECT_ENGINE_INSPECT_BUFFER_H +#define SURICATA_DETECT_ENGINE_INSPECT_BUFFER_H + +/* inspection buffer is a simple structure that is passed between prefilter, + * transformation functions and inspection functions. + * Initially setup with 'orig' ptr and len, transformations can then take + * then and fill the 'buf'. Multiple transformations can update the buffer, + * both growing and shrinking it. + * Prefilter and inspection will only deal with 'inspect'. */ + +typedef struct InspectionBuffer { + const uint8_t *inspect; /**< active pointer, points either to ::buf or ::orig */ + uint64_t inspect_offset; + uint32_t inspect_len; /**< size of active data. See to ::len or ::orig_len */ + bool initialized; /**< is initialized. ::inspect might be NULL if transform lead to 0 size */ + uint8_t flags; /**< DETECT_CI_FLAGS_* for use with DetectEngineContentInspection */ +#ifdef DEBUG_VALIDATION + bool multi; +#endif + uint32_t len; /**< how much is in use */ + uint8_t *buf; + uint32_t size; /**< size of the memory allocation */ + + uint32_t orig_len; + const uint8_t *orig; +} InspectionBuffer; + +// Forward declarations for types from detect.h +typedef struct DetectEngineThreadCtx_ DetectEngineThreadCtx; +typedef struct DetectEngineTransforms DetectEngineTransforms; +typedef struct SigMatch_ SigMatch; + +void InspectionBufferInit(InspectionBuffer *buffer, uint32_t initial_size); +void InspectionBufferSetup(DetectEngineThreadCtx *det_ctx, const int list_id, + InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len); +void InspectionBufferSetupAndApplyTransforms(DetectEngineThreadCtx *det_ctx, const int list_id, + InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len, + const DetectEngineTransforms *transforms); +void InspectionBufferFree(InspectionBuffer *buffer); +uint8_t *SCInspectionBufferCheckAndExpand(InspectionBuffer *buffer, uint32_t min_size); +void SCInspectionBufferTruncate(InspectionBuffer *buffer, uint32_t buf_len); +void InspectionBufferCopy(InspectionBuffer *buffer, uint8_t *buf, uint32_t buf_len); +void InspectionBufferApplyTransforms(DetectEngineThreadCtx *det_ctx, InspectionBuffer *buffer, + const DetectEngineTransforms *transforms); +void InspectionBufferClean(DetectEngineThreadCtx *det_ctx); +InspectionBuffer *InspectionBufferGet(DetectEngineThreadCtx *det_ctx, const int list_id); +void InspectionBufferSetupMultiEmpty(InspectionBuffer *buffer); +void InspectionBufferSetupMulti(DetectEngineThreadCtx *det_ctx, InspectionBuffer *buffer, + const DetectEngineTransforms *transforms, const uint8_t *data, const uint32_t data_len); +InspectionBuffer *InspectionBufferMultipleForListGet( + DetectEngineThreadCtx *det_ctx, const int list_id, uint32_t local_id); + +#endif /* SURICATA_DETECT_ENGINE_INSPECT_BUFFER_H */ diff --git a/src/detect-engine.c b/src/detect-engine.c index 0a381f9408..f0ff76fc1f 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -105,9 +105,6 @@ static uint32_t DetectEngineTenantGetIdFromLivedev(const void *ctx, const Packet static uint32_t DetectEngineTenantGetIdFromVlanId(const void *ctx, const Packet *p); static uint32_t DetectEngineTenantGetIdFromPcap(const void *ctx, const Packet *p); -static inline void InspectionBufferApplyTransformsInternal( - DetectEngineThreadCtx *det_ctx, InspectionBuffer *, const DetectEngineTransforms *); - static DetectEngineAppInspectionEngine *g_app_inspect_engines = NULL; static DetectEnginePktInspectionEngine *g_pkt_inspect_engines = NULL; static DetectEngineFrameInspectionEngine *g_frame_inspect_engines = NULL; @@ -1398,237 +1395,6 @@ bool DetectBufferIsPresent(const Signature *s, const uint32_t buf_id) return false; } -void InspectionBufferClean(DetectEngineThreadCtx *det_ctx) -{ - /* single buffers */ - for (uint32_t i = 0; i < det_ctx->inspect.to_clear_idx; i++) - { - const uint32_t idx = det_ctx->inspect.to_clear_queue[i]; - InspectionBuffer *buffer = &det_ctx->inspect.buffers[idx]; - buffer->inspect = NULL; - buffer->initialized = false; - } - det_ctx->inspect.to_clear_idx = 0; - - /* multi buffers */ - for (uint32_t i = 0; i < det_ctx->multi_inspect.to_clear_idx; i++) - { - const uint32_t idx = det_ctx->multi_inspect.to_clear_queue[i]; - InspectionBufferMultipleForList *mbuffer = &det_ctx->multi_inspect.buffers[idx]; - for (uint32_t x = 0; x <= mbuffer->max; x++) { - InspectionBuffer *buffer = &mbuffer->inspection_buffers[x]; - buffer->inspect = NULL; - buffer->initialized = false; - } - mbuffer->init = 0; - mbuffer->max = 0; - } - det_ctx->multi_inspect.to_clear_idx = 0; -} - -InspectionBuffer *InspectionBufferGet(DetectEngineThreadCtx *det_ctx, const int list_id) -{ - return &det_ctx->inspect.buffers[list_id]; -} - -static InspectionBufferMultipleForList *InspectionBufferGetMulti( - DetectEngineThreadCtx *det_ctx, const int list_id) -{ - InspectionBufferMultipleForList *buffer = &det_ctx->multi_inspect.buffers[list_id]; - if (!buffer->init) { - det_ctx->multi_inspect.to_clear_queue[det_ctx->multi_inspect.to_clear_idx++] = list_id; - buffer->init = 1; - } - return buffer; -} - -/** \brief for a InspectionBufferMultipleForList get a InspectionBuffer - * \param fb the multiple buffer array - * \param local_id the index to get a buffer - * \param buffer the inspect buffer or NULL in case of error */ -InspectionBuffer *InspectionBufferMultipleForListGet( - DetectEngineThreadCtx *det_ctx, const int list_id, const uint32_t local_id) -{ - if (unlikely(local_id >= 1024)) { - DetectEngineSetEvent(det_ctx, DETECT_EVENT_TOO_MANY_BUFFERS); - return NULL; - } - - InspectionBufferMultipleForList *fb = InspectionBufferGetMulti(det_ctx, list_id); - - if (local_id >= fb->size) { - uint32_t old_size = fb->size; - uint32_t new_size = local_id + 1; - uint32_t grow_by = new_size - old_size; - SCLogDebug("size is %u, need %u, so growing by %u", old_size, new_size, grow_by); - - SCLogDebug("fb->inspection_buffers %p", fb->inspection_buffers); - void *ptr = SCRealloc(fb->inspection_buffers, (local_id + 1) * sizeof(InspectionBuffer)); - if (ptr == NULL) - return NULL; - - InspectionBuffer *to_zero = (InspectionBuffer *)ptr + old_size; - SCLogDebug("ptr %p to_zero %p", ptr, to_zero); - memset((uint8_t *)to_zero, 0, (grow_by * sizeof(InspectionBuffer))); - fb->inspection_buffers = ptr; - fb->size = new_size; - } - - fb->max = MAX(fb->max, local_id); - InspectionBuffer *buffer = &fb->inspection_buffers[local_id]; - SCLogDebug("using buffer %p", buffer); -#ifdef DEBUG_VALIDATION - buffer->multi = true; -#endif - return buffer; -} - -static inline void InspectionBufferApplyTransformsInternal(DetectEngineThreadCtx *det_ctx, - InspectionBuffer *buffer, const DetectEngineTransforms *transforms) -{ - if (transforms) { - for (int i = 0; i < DETECT_TRANSFORMS_MAX; i++) { - const int id = transforms->transforms[i].transform; - if (id == 0) - break; - BUG_ON(sigmatch_table[id].Transform == NULL); - sigmatch_table[id].Transform(det_ctx, buffer, transforms->transforms[i].options); - SCLogDebug("applied transform %s", sigmatch_table[id].name); - } - } -} - -void InspectionBufferApplyTransforms(DetectEngineThreadCtx *det_ctx, InspectionBuffer *buffer, - const DetectEngineTransforms *transforms) -{ - InspectionBufferApplyTransformsInternal(det_ctx, buffer, transforms); -} - -void InspectionBufferInit(InspectionBuffer *buffer, uint32_t initial_size) -{ - memset(buffer, 0, sizeof(*buffer)); - buffer->buf = SCCalloc(initial_size, sizeof(uint8_t)); - if (buffer->buf != NULL) { - buffer->size = initial_size; - } -} - -/** \brief setup the buffer empty */ -void InspectionBufferSetupMultiEmpty(InspectionBuffer *buffer) -{ -#ifdef DEBUG_VALIDATION - DEBUG_VALIDATE_BUG_ON(buffer->initialized); - DEBUG_VALIDATE_BUG_ON(!buffer->multi); -#endif - buffer->inspect = NULL; - buffer->inspect_len = 0; - buffer->len = 0; - buffer->initialized = true; -} - -/** \brief setup the buffer with our initial data */ -void InspectionBufferSetupMulti(DetectEngineThreadCtx *det_ctx, InspectionBuffer *buffer, - const DetectEngineTransforms *transforms, const uint8_t *data, const uint32_t data_len) -{ -#ifdef DEBUG_VALIDATION - DEBUG_VALIDATE_BUG_ON(!buffer->multi); -#endif - buffer->inspect = buffer->orig = data; - buffer->inspect_len = buffer->orig_len = data_len; - buffer->len = 0; - buffer->initialized = true; - - InspectionBufferApplyTransformsInternal(det_ctx, buffer, transforms); -} - -static inline void InspectionBufferSetupInternal(DetectEngineThreadCtx *det_ctx, const int list_id, - InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len) -{ -#ifdef DEBUG_VALIDATION - DEBUG_VALIDATE_BUG_ON(buffer->multi); - DEBUG_VALIDATE_BUG_ON(buffer != InspectionBufferGet(det_ctx, list_id)); -#endif - if (buffer->inspect == NULL) { -#ifdef UNITTESTS - if (det_ctx && list_id != -1) -#endif - det_ctx->inspect.to_clear_queue[det_ctx->inspect.to_clear_idx++] = list_id; - } - buffer->inspect = buffer->orig = data; - buffer->inspect_len = buffer->orig_len = data_len; - buffer->len = 0; - buffer->initialized = true; -} -/** \brief setup the buffer with our initial data */ -void InspectionBufferSetup(DetectEngineThreadCtx *det_ctx, const int list_id, - InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len) -{ - InspectionBufferSetupInternal(det_ctx, list_id, buffer, data, data_len); -} - -/** \brief setup the buffer with our initial data */ -void InspectionBufferSetupAndApplyTransforms(DetectEngineThreadCtx *det_ctx, const int list_id, - InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len, - const DetectEngineTransforms *transforms) -{ - InspectionBufferSetupInternal(det_ctx, list_id, buffer, data, data_len); - InspectionBufferApplyTransformsInternal(det_ctx, buffer, transforms); -} - -void InspectionBufferFree(InspectionBuffer *buffer) -{ - if (buffer->buf != NULL) { - SCFree(buffer->buf); - } - memset(buffer, 0, sizeof(*buffer)); -} - -/** - * \brief make sure that the buffer has at least 'min_size' bytes - * Expand the buffer if necessary - */ -void *InspectionBufferCheckAndExpand(InspectionBuffer *buffer, uint32_t min_size) -{ - if (likely(buffer->size >= min_size)) - return buffer->buf; - - uint32_t new_size = (buffer->size == 0) ? 4096 : buffer->size; - while (new_size < min_size) { - new_size *= 2; - } - - void *ptr = SCRealloc(buffer->buf, new_size); - if (ptr != NULL) { - buffer->buf = ptr; - buffer->size = new_size; - } else { - return NULL; - } - return buffer->buf; -} - -void InspectionBufferTruncate(InspectionBuffer *buffer, uint32_t buf_len) -{ - DEBUG_VALIDATE_BUG_ON(buffer->buf == NULL); - DEBUG_VALIDATE_BUG_ON(buf_len > buffer->size); - buffer->inspect = buffer->buf; - buffer->inspect_len = buf_len; - buffer->initialized = true; -} - -void InspectionBufferCopy(InspectionBuffer *buffer, uint8_t *buf, uint32_t buf_len) -{ - InspectionBufferCheckAndExpand(buffer, buf_len); - - if (buffer->size) { - uint32_t copy_size = MIN(buf_len, buffer->size); - memcpy(buffer->buf, buf, copy_size); - buffer->inspect = buffer->buf; - buffer->inspect_len = copy_size; - buffer->initialized = true; - } -} - /** \brief Check content byte array compatibility with transforms * * The "content" array is presented to the transforms so that each diff --git a/src/detect-engine.h b/src/detect-engine.h index f033c632ad..3a883289a8 100644 --- a/src/detect-engine.h +++ b/src/detect-engine.h @@ -27,26 +27,6 @@ #include "detect.h" #include "suricata.h" -void InspectionBufferInit(InspectionBuffer *buffer, uint32_t initial_size); -void InspectionBufferSetup(DetectEngineThreadCtx *det_ctx, const int list_id, - InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len); -void InspectionBufferSetupAndApplyTransforms(DetectEngineThreadCtx *det_ctx, const int list_id, - InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len, - const DetectEngineTransforms *transforms); -void InspectionBufferFree(InspectionBuffer *buffer); -void *InspectionBufferCheckAndExpand(InspectionBuffer *buffer, uint32_t min_size); -void InspectionBufferTruncate(InspectionBuffer *buffer, uint32_t buf_len); -void InspectionBufferCopy(InspectionBuffer *buffer, uint8_t *buf, uint32_t buf_len); -void InspectionBufferApplyTransforms(DetectEngineThreadCtx *det_ctx, InspectionBuffer *buffer, - const DetectEngineTransforms *transforms); -void InspectionBufferClean(DetectEngineThreadCtx *det_ctx); -InspectionBuffer *InspectionBufferGet(DetectEngineThreadCtx *det_ctx, const int list_id); -void InspectionBufferSetupMultiEmpty(InspectionBuffer *buffer); -void InspectionBufferSetupMulti(DetectEngineThreadCtx *det_ctx, InspectionBuffer *buffer, - const DetectEngineTransforms *transforms, const uint8_t *data, const uint32_t data_len); -InspectionBuffer *InspectionBufferMultipleForListGet( - DetectEngineThreadCtx *det_ctx, const int list_id, uint32_t local_id); - /* start up registry funcs */ int DetectBufferTypeRegister(const char *name); diff --git a/src/detect.h b/src/detect.h index 148245442a..d05c943a7f 100644 --- a/src/detect.h +++ b/src/detect.h @@ -31,6 +31,7 @@ #include "detect-reference.h" #include "detect-metadata.h" #include "detect-engine-register.h" +#include "detect-engine-inspect-buffer.h" #include "util-prefilter.h" #include "util-mpm.h" @@ -370,30 +371,6 @@ typedef struct SigMatchData_ { struct DetectEngineThreadCtx_;// DetectEngineThreadCtx; -/* inspection buffer is a simple structure that is passed between prefilter, - * transformation functions and inspection functions. - * Initially setup with 'orig' ptr and len, transformations can then take - * then and fill the 'buf'. Multiple transformations can update the buffer, - * both growing and shrinking it. - * Prefilter and inspection will only deal with 'inspect'. */ - -typedef struct InspectionBuffer { - const uint8_t *inspect; /**< active pointer, points either to ::buf or ::orig */ - uint64_t inspect_offset; - uint32_t inspect_len; /**< size of active data. See to ::len or ::orig_len */ - bool initialized; /**< is initialized. ::inspect might be NULL if transform lead to 0 size */ - uint8_t flags; /**< DETECT_CI_FLAGS_* for use with DetectEngineContentInspection */ -#ifdef DEBUG_VALIDATION - bool multi; -#endif - uint32_t len; /**< how much is in use */ - uint8_t *buf; - uint32_t size; /**< size of the memory allocation */ - - uint32_t orig_len; - const uint8_t *orig; -} InspectionBuffer; - /* inspection buffers are kept per tx (in det_ctx), but some protocols * need a bit more. A single TX might have multiple buffers, e.g. files in * SMTP or DNS queries. Since all prefilters+transforms run before the diff --git a/src/util-file-decompression.c b/src/util-file-decompression.c index dfafdc87f0..ffff78e388 100644 --- a/src/util-file-decompression.c +++ b/src/util-file-decompression.c @@ -129,7 +129,7 @@ int FileSwfDecompression(const uint8_t *buffer, uint32_t buffer_len, decompressed_data_len += 8; /* make sure the inspection buffer has enough space */ - InspectionBufferCheckAndExpand(out_buffer, decompressed_data_len); + SCInspectionBufferCheckAndExpand(out_buffer, decompressed_data_len); if (out_buffer->size < decompressed_data_len) { DetectEngineSetEvent(det_ctx, FILE_DECODER_EVENT_NO_MEM); return 0; -- 2.47.3