detect: rust helper to register sticky buffer

pull/13053/head
Philippe Antoine 9 months ago committed by Victor Julien
parent 96afdce283
commit aa7f926ff4

@ -36,6 +36,7 @@ pub mod vlan;
pub mod datasets; pub mod datasets;
use std::os::raw::{c_char, c_int, c_void}; use std::os::raw::{c_char, c_int, c_void};
use std::ffi::CString;
use suricata_sys::sys::AppProto; use suricata_sys::sys::AppProto;
@ -55,6 +56,61 @@ pub trait EnumString<T> {
fn from_str(s: &str) -> Option<Self> where Self: Sized; fn from_str(s: &str) -> Option<Self> where Self: Sized;
} }
/// Rust app-layer light version of SigTableElmt for simple sticky buffer
pub struct SigTableElmtStickyBuffer {
/// keyword name
pub name: String,
/// keyword description
pub desc: String,
/// keyword documentation url
pub url: String,
/// function callback to parse and setup keyword in rule
pub setup: unsafe extern "C" fn(
de: *mut c_void,
s: *mut c_void,
raw: *const std::os::raw::c_char,
) -> c_int,
}
pub fn helper_keyword_register_sticky_buffer(kw: &SigTableElmtStickyBuffer) -> c_int {
let name = CString::new(kw.name.as_bytes()).unwrap().into_raw();
let desc = CString::new(kw.desc.as_bytes()).unwrap().into_raw();
let url = CString::new(kw.url.as_bytes()).unwrap().into_raw();
let st = SCSigTableAppLiteElmt {
name,
desc,
url,
Setup: kw.setup,
flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER,
AppLayerTxMatch: None,
Free: None,
};
unsafe {
let r = DetectHelperKeywordRegister(&st);
DetectHelperKeywordSetCleanCString(r);
return r;
}
}
#[repr(C)]
#[allow(non_snake_case)]
/// Names of SigTableElmt for release by rust
pub struct SCSigTableNamesElmt {
/// keyword name
pub name: *mut libc::c_char,
/// keyword description
pub desc: *mut libc::c_char,
/// keyword documentation url
pub url: *mut libc::c_char,
}
#[no_mangle]
pub unsafe extern "C" fn SCDetectSigMatchNamesFree(kw: &mut SCSigTableNamesElmt) {
let _ = CString::from_raw(kw.name);
let _ = CString::from_raw(kw.desc);
let _ = CString::from_raw(kw.url);
}
#[repr(C)] #[repr(C)]
#[allow(non_snake_case)] #[allow(non_snake_case)]
/// App-layer light version of SigTableElmt /// App-layer light version of SigTableElmt
@ -95,6 +151,7 @@ pub const SIGMATCH_INFO_STICKY_BUFFER: u16 = 0x200; // BIT_U16(9)
/// cbindgen:ignore /// cbindgen:ignore
extern "C" { extern "C" {
pub fn DetectHelperKeywordSetCleanCString(id: c_int);
pub fn DetectBufferSetActiveList(de: *mut c_void, s: *mut c_void, bufid: c_int) -> c_int; pub fn DetectBufferSetActiveList(de: *mut c_void, s: *mut c_void, bufid: c_int) -> c_int;
pub fn DetectHelperGetData( pub fn DetectHelperGetData(
de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8, de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8,

@ -21,10 +21,10 @@ use crate::detect::uint::{
SCDetectU8Parse, SCDetectU8Parse,
}; };
use crate::detect::{ use crate::detect::{
DetectBufferSetActiveList, DetectHelperBufferRegister, DetectHelperGetMultiData, helper_keyword_register_sticky_buffer, DetectBufferSetActiveList, DetectHelperBufferRegister,
DetectHelperKeywordAliasRegister, DetectHelperKeywordRegister, DetectHelperGetMultiData, DetectHelperKeywordAliasRegister, DetectHelperKeywordRegister,
DetectHelperMultiBufferProgressMpmRegister, DetectSignatureSetAppProto, SCSigTableAppLiteElmt, DetectHelperMultiBufferProgressMpmRegister, DetectSignatureSetAppProto, SCSigTableAppLiteElmt,
SigMatchAppendSMToList, SIGMATCH_INFO_STICKY_BUFFER, SIGMATCH_NOOPT, SigMatchAppendSMToList, SigTableElmtStickyBuffer,
}; };
use crate::direction::Direction; use crate::direction::Direction;
use std::ffi::CStr; use std::ffi::CStr;
@ -366,16 +366,13 @@ unsafe extern "C" fn dns_query_get_data_wrapper(
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn SCDetectDNSRegister() { pub unsafe extern "C" fn SCDetectDNSRegister() {
let kw = SCSigTableAppLiteElmt { let kw = SigTableElmtStickyBuffer {
name: b"dns.answer.name\0".as_ptr() as *const libc::c_char, name: String::from("dns.answer.name"),
desc: b"DNS answer name sticky buffer\0".as_ptr() as *const libc::c_char, desc: String::from("DNS answer name sticky buffer"),
url: b"/rules/dns-keywords.html#dns-answer-name\0".as_ptr() as *const libc::c_char, url: String::from("/rules/dns-keywords.html#dns-answer-name"),
Setup: dns_detect_answer_name_setup, setup: dns_detect_answer_name_setup,
flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER,
AppLayerTxMatch: None,
Free: None,
}; };
let _g_dns_answer_name_kw_id = DetectHelperKeywordRegister(&kw); let _g_dns_answer_name_kw_id = helper_keyword_register_sticky_buffer(&kw);
G_DNS_ANSWER_NAME_BUFFER_ID = DetectHelperMultiBufferProgressMpmRegister( G_DNS_ANSWER_NAME_BUFFER_ID = DetectHelperMultiBufferProgressMpmRegister(
b"dns.answer.name\0".as_ptr() as *const libc::c_char, b"dns.answer.name\0".as_ptr() as *const libc::c_char,
b"dns answer name\0".as_ptr() as *const libc::c_char, b"dns answer name\0".as_ptr() as *const libc::c_char,
@ -403,16 +400,13 @@ pub unsafe extern "C" fn SCDetectDNSRegister() {
true, true,
true, true,
); );
let kw = SCSigTableAppLiteElmt { let kw = SigTableElmtStickyBuffer {
name: b"dns.query.name\0".as_ptr() as *const libc::c_char, name: String::from("dns.query.name"),
desc: b"DNS query name sticky buffer\0".as_ptr() as *const libc::c_char, desc: String::from("DNS query name sticky buffer"),
url: b"/rules/dns-keywords.html#dns-query-name\0".as_ptr() as *const libc::c_char, url: String::from("/rules/dns-keywords.html#dns-query-name"),
Setup: dns_detect_query_name_setup, setup: dns_detect_query_name_setup,
flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER,
AppLayerTxMatch: None,
Free: None,
}; };
let _g_dns_query_name_kw_id = DetectHelperKeywordRegister(&kw); let _g_dns_query_name_kw_id = helper_keyword_register_sticky_buffer(&kw);
G_DNS_QUERY_NAME_BUFFER_ID = DetectHelperMultiBufferProgressMpmRegister( G_DNS_QUERY_NAME_BUFFER_ID = DetectHelperMultiBufferProgressMpmRegister(
b"dns.query.name\0".as_ptr() as *const libc::c_char, b"dns.query.name\0".as_ptr() as *const libc::c_char,
b"dns query name\0".as_ptr() as *const libc::c_char, b"dns query name\0".as_ptr() as *const libc::c_char,
@ -456,16 +450,13 @@ pub unsafe extern "C" fn SCDetectDNSRegister() {
true, true,
true, true,
); );
let kw = SCSigTableAppLiteElmt { let kw = SigTableElmtStickyBuffer {
name: b"dns.query\0".as_ptr() as *const libc::c_char, name: String::from("dns.query"),
desc: b"sticky buffer to match DNS query-buffer\0".as_ptr() as *const libc::c_char, desc: String::from("sticky buffer to match DNS query-buffer"),
url: b"/rules/dns-keywords.html#dns-query\0".as_ptr() as *const libc::c_char, url: String::from("/rules/dns-keywords.html#dns-query"),
Setup: dns_detect_query_setup, setup: dns_detect_query_setup,
flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER,
AppLayerTxMatch: None,
Free: None,
}; };
let g_dns_query_name_kw_id = DetectHelperKeywordRegister(&kw); let g_dns_query_name_kw_id = helper_keyword_register_sticky_buffer(&kw);
DetectHelperKeywordAliasRegister( DetectHelperKeywordAliasRegister(
g_dns_query_name_kw_id, g_dns_query_name_kw_id,
b"dns_query\0".as_ptr() as *const libc::c_char, b"dns_query\0".as_ptr() as *const libc::c_char,

@ -447,9 +447,30 @@ static void DetectFileHandlerRegister(void)
} }
} }
static void SigCleanCString(SigTableElmt *base)
{
SCSigTableNamesElmt kw;
// remove const for mut to release
kw.name = (char *)base->name;
kw.desc = (char *)base->desc;
kw.url = (char *)base->url;
SCDetectSigMatchNamesFree(&kw);
}
void DetectHelperKeywordSetCleanCString(int id)
{
sigmatch_table[id].Cleanup = SigCleanCString;
}
void SigTableCleanup(void) void SigTableCleanup(void)
{ {
if (sigmatch_table != NULL) { if (sigmatch_table != NULL) {
for (int i = 0; i < DETECT_TBLSIZE; i++) {
if ((sigmatch_table[i].Cleanup) == NULL) {
continue;
}
sigmatch_table[i].Cleanup(&sigmatch_table[i]);
}
SCFree(sigmatch_table); SCFree(sigmatch_table);
sigmatch_table = NULL; sigmatch_table = NULL;
DETECT_TBLSIZE = 0; DETECT_TBLSIZE = 0;

@ -349,5 +349,6 @@ void SigTableSetup(void);
int SCSigTablePreRegister(void (*KeywordsRegister)(void)); int SCSigTablePreRegister(void (*KeywordsRegister)(void));
void SigTableRegisterTests(void); void SigTableRegisterTests(void);
bool SigTableHasKeyword(const char *keyword); bool SigTableHasKeyword(const char *keyword);
void DetectHelperKeywordSetCleanCString(int id);
#endif /* SURICATA_DETECT_ENGINE_REGISTER_H */ #endif /* SURICATA_DETECT_ENGINE_REGISTER_H */

@ -1404,6 +1404,8 @@ typedef struct SigTableElmt_ {
const char *desc; const char *desc;
const char *url; const char *url;
// Cleanup function for freeing rust allocated name or such
void (*Cleanup)(struct SigTableElmt_ *);
} SigTableElmt; } SigTableElmt;
/* event code */ /* event code */

Loading…
Cancel
Save