src: new file detect-engine-inspect-buffer.h

For InspectionBuffer structure and related functions

Bindgen it for rust, especially transforms

Ticket: 7667
pull/13207/head
Philippe Antoine 2 years ago committed by Victor Julien
parent df0dc2e8ea
commit fd7bd9c200

@ -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 {

@ -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 {

@ -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]

@ -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]

@ -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]

@ -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]

@ -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);
}

@ -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(

@ -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]

@ -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) {

@ -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)]

@ -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 \

@ -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"

@ -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;
}

@ -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 */

@ -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 <victor@inliniac.net>
*/
#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;
}
}

@ -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 <victor@inliniac.net>
*/
#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 */

@ -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

@ -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);

@ -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

@ -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;

Loading…
Cancel
Save