From 3ada5e148006450053bab24325973b4bdc074f8b Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Thu, 26 Nov 2020 16:21:46 -0600 Subject: [PATCH] rust/ffi: provide AppLayerRegisterParser in context AppLayerRegisterParser was creating a link error when attempting to use a convenience library for the Suricata C code, then linking the library of C code with the library of Rust code into a final Suricata executable, or use with fuzz targets. By moving AppLayerRegisterParser to the context structure and calling it like a callback the circular reference is removed allowing the convenience libraries to work again. This is also a stepping block to proving a Suricata library as a single .a or .so file. --- rust/src/applayer.rs | 7 ++++++- rust/src/core.rs | 2 ++ src/rust-context.h | 4 ++++ src/suricata.c | 3 +++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index 476ea1cb3..684d0f275 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -22,6 +22,7 @@ use crate::core::{DetectEngineState,Flow,AppLayerEventType,AppLayerDecoderEvents use crate::filecontainer::FileContainer; use crate::applayer; use std::os::raw::{c_void,c_char,c_int}; +use crate::core::SC; #[repr(C)] #[derive(Debug,PartialEq)] @@ -289,7 +290,11 @@ pub type TruncateFn = unsafe extern "C" fn (*mut c_void, u8); // Defined in app-layer-register.h extern { pub fn AppLayerRegisterProtocolDetection(parser: *const RustParser, enable_default: c_int) -> AppProto; - pub fn AppLayerRegisterParser(parser: *const RustParser, alproto: AppProto) -> c_int; +} + +#[allow(non_snake_case)] +pub unsafe fn AppLayerRegisterParser(parser: *const RustParser, alproto: AppProto) -> c_int { + (SC.unwrap().AppLayerRegisterParser)(parser, alproto) } // Defined in app-layer-detect-proto.h diff --git a/rust/src/core.rs b/rust/src/core.rs index db9293032..69ed658a2 100644 --- a/rust/src/core.rs +++ b/rust/src/core.rs @@ -141,6 +141,8 @@ pub struct SuricataContext { pub FileContainerRecycle: SCFileContainerRecycle, pub FilePrune: SCFilePrune, pub FileSetTx: SCFileSetTx, + + pub AppLayerRegisterParser: extern fn(parser: *const crate::applayer::RustParser, alproto: AppProto) -> std::os::raw::c_int, } #[allow(non_snake_case)] diff --git a/src/rust-context.h b/src/rust-context.h index 8efd2678a..f0005314f 100644 --- a/src/rust-context.h +++ b/src/rust-context.h @@ -25,6 +25,8 @@ #include "app-layer-snmp.h" //SNMPState, SNMPTransaction #include "app-layer-tftp.h" //TFTPState, TFTPTransaction +struct AppLayerParser; + typedef struct SuricataContext_ { SCError (*SCLogMessage)(const SCLogLevel, const char *, const unsigned int, const char *, const SCError, const char *message); @@ -46,6 +48,8 @@ typedef struct SuricataContext_ { void (*FilePrune)(FileContainer *ffc); void (*FileSetTx)(FileContainer *, uint64_t); + int (*AppLayerRegisterParser)(const struct AppLayerParser *p, AppProto alproto); + } SuricataContext; extern SuricataContext suricata_context; diff --git a/src/suricata.c b/src/suricata.c index 5b80e974a..f386dc415 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -113,6 +113,7 @@ #include "app-layer.h" #include "app-layer-parser.h" +#include "app-layer-register.h" #include "app-layer-htp.h" #include "app-layer-ssl.h" #include "app-layer-ssh.h" @@ -2661,6 +2662,8 @@ int InitGlobal(void) { suricata_context.FilePrune = FilePrune; suricata_context.FileSetTx = FileContainerSetTx; + suricata_context.AppLayerRegisterParser = AppLayerRegisterParser; + rs_init(&suricata_context); SC_ATOMIC_INIT(engine_stage); -- 2.47.2