Skip to content

Commit

Permalink
app-layer: use uint8_t consistent for event IDs
Browse files Browse the repository at this point in the history
Introduce a common function for mapping names to IDs that performs
bounds checking.

Note: For event IDs in the enum that are larger than a uint8_t, -1
will be returned instead of -4. -4 has special meaning during
signature parsin that means requirements were not met. -4 has no
special handling prior to requirements, or the meaning has been lost.
  • Loading branch information
jasonish committed Oct 23, 2024
1 parent 1860aa8 commit b1e6031
Show file tree
Hide file tree
Showing 15 changed files with 115 additions and 140 deletions.
10 changes: 5 additions & 5 deletions rust/derive/src/applayerevent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub fn derive_app_layer_event(input: TokenStream) -> TokenStream {
let cname = format!("{}\0", event_name);
event_names.push(event_name);
event_cstrings.push(cname);
event_ids.push(i as i32);
event_ids.push(i as u8);
}
}
_ => panic!("AppLayerEvent can only be derived for enums"),
Expand All @@ -60,14 +60,14 @@ pub fn derive_app_layer_event(input: TokenStream) -> TokenStream {

let expanded = quote! {
impl #crate_id::applayer::AppLayerEvent for #name {
fn from_id(id: i32) -> Option<#name> {
fn from_id(id: u8) -> Option<#name> {
match id {
#( #event_ids => Some(#name::#fields) ,)*
_ => None,
}
}

fn as_i32(&self) -> i32 {
fn as_u8(&self) -> u8 {
match *self {
#( #name::#fields => #event_ids ,)*
}
Expand All @@ -88,14 +88,14 @@ pub fn derive_app_layer_event(input: TokenStream) -> TokenStream {

unsafe extern "C" fn get_event_info(
event_name: *const std::os::raw::c_char,
event_id: *mut std::os::raw::c_int,
event_id: *mut u8,
event_type: *mut #crate_id::core::AppLayerEventType,
) -> std::os::raw::c_int {
#crate_id::applayer::get_event_info::<#name>(event_name, event_id, event_type)
}

unsafe extern "C" fn get_event_info_by_id(
event_id: std::os::raw::c_int,
event_id: u8,
event_name: *mut *const std::os::raw::c_char,
event_type: *mut #crate_id::core::AppLayerEventType,
) -> std::os::raw::c_int {
Expand Down
24 changes: 13 additions & 11 deletions rust/src/applayer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,8 @@ pub type StateTxFreeFn = unsafe extern "C" fn (*mut c_void, u64);
pub type StateGetTxFn = unsafe extern "C" fn (*mut c_void, u64) -> *mut c_void;
pub type StateGetTxCntFn = unsafe extern "C" fn (*mut c_void) -> u64;
pub type StateGetProgressFn = unsafe extern "C" fn (*mut c_void, u8) -> c_int;
pub type GetEventInfoFn = unsafe extern "C" fn (*const c_char, *mut c_int, *mut AppLayerEventType) -> c_int;
pub type GetEventInfoByIdFn = unsafe extern "C" fn (c_int, *mut *const c_char, *mut AppLayerEventType) -> c_int;
pub type GetEventInfoFn = unsafe extern "C" fn (*const c_char, event_id: *mut u8, *mut AppLayerEventType) -> c_int;
pub type GetEventInfoByIdFn = unsafe extern "C" fn (event_id: u8, *mut *const c_char, *mut AppLayerEventType) -> c_int;
pub type LocalStorageNewFn = extern "C" fn () -> *mut c_void;
pub type LocalStorageFreeFn = extern "C" fn (*mut c_void);
pub type GetTxFilesFn = unsafe extern "C" fn (*mut c_void, u8) -> AppLayerGetFileState;
Expand Down Expand Up @@ -569,7 +569,7 @@ impl LoggerFlags {
/// derive AppLayerEvent.
pub trait AppLayerEvent {
/// Return the enum variant of the given ID.
fn from_id(id: i32) -> Option<Self> where Self: std::marker::Sized;
fn from_id(id: u8) -> Option<Self> where Self: std::marker::Sized;

/// Convert the enum variant to a C-style string (suffixed with \0).
fn to_cstring(&self) -> &str;
Expand All @@ -578,16 +578,16 @@ pub trait AppLayerEvent {
fn from_string(s: &str) -> Option<Self> where Self: std::marker::Sized;

/// Return the ID value of the enum variant.
fn as_i32(&self) -> i32;
fn as_u8(&self) -> u8;

unsafe extern "C" fn get_event_info(
event_name: *const std::os::raw::c_char,
event_id: *mut std::os::raw::c_int,
event_id: *mut u8,
event_type: *mut core::AppLayerEventType,
) -> std::os::raw::c_int;

unsafe extern "C" fn get_event_info_by_id(
event_id: std::os::raw::c_int,
event_id: u8,
event_name: *mut *const std::os::raw::c_char,
event_type: *mut core::AppLayerEventType,
) -> std::os::raw::c_int;
Expand All @@ -611,27 +611,29 @@ pub trait AppLayerEvent {
#[inline(always)]
pub unsafe fn get_event_info<T: AppLayerEvent>(
event_name: *const std::os::raw::c_char,
event_id: *mut std::os::raw::c_int,
event_id: *mut u8,
event_type: *mut core::AppLayerEventType,
) -> std::os::raw::c_int {
if event_name.is_null() {
return -1;
}

let event = match CStr::from_ptr(event_name).to_str().map(T::from_string) {
Ok(Some(event)) => event.as_i32(),
_ => -1,
Ok(Some(event)) => event.as_u8(),
_ => {
return -1;
}
};
*event_type = core::AppLayerEventType::APP_LAYER_EVENT_TYPE_TRANSACTION;
*event_id = event as std::os::raw::c_int;
*event_id = event;
return 0;
}

/// Generic `get_info_info_by_id` implementation for enums implementing
/// AppLayerEvent.
#[inline(always)]
pub unsafe fn get_event_info_by_id<T: AppLayerEvent>(
event_id: std::os::raw::c_int,
event_id: u8,
event_name: *mut *const std::os::raw::c_char,
event_type: *mut core::AppLayerEventType,
) -> std::os::raw::c_int {
Expand Down
4 changes: 2 additions & 2 deletions rust/src/ftp/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub enum FtpEvent {
/// Unsafe as called from C.
#[no_mangle]
pub unsafe extern "C" fn ftp_get_event_info(
event_name: *const c_char, event_id: *mut c_int, event_type: *mut AppLayerEventType,
event_name: *const c_char, event_id: *mut u8, event_type: *mut AppLayerEventType,
) -> c_int {
crate::applayer::get_event_info::<FtpEvent>(event_name, event_id, event_type)
}
Expand All @@ -44,7 +44,7 @@ pub unsafe extern "C" fn ftp_get_event_info(
/// Unsafe as called from C.
#[no_mangle]
pub unsafe extern "C" fn ftp_get_event_info_by_id(
event_id: c_int, event_name: *mut *const c_char, event_type: *mut AppLayerEventType,
event_id: u8, event_name: *mut *const c_char, event_type: *mut AppLayerEventType,
) -> c_int {
crate::applayer::get_event_info_by_id::<FtpEvent>(event_id, event_name, event_type) as c_int
}
4 changes: 2 additions & 2 deletions rust/src/smb/smb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2203,7 +2203,7 @@ pub unsafe extern "C" fn rs_smb_get_tx_data(

#[no_mangle]
pub unsafe extern "C" fn rs_smb_state_get_event_info_by_id(
event_id: std::os::raw::c_int,
event_id: u8,
event_name: *mut *const std::os::raw::c_char,
event_type: *mut AppLayerEventType,
) -> std::os::raw::c_int {
Expand All @@ -2213,7 +2213,7 @@ pub unsafe extern "C" fn rs_smb_state_get_event_info_by_id(
#[no_mangle]
pub unsafe extern "C" fn rs_smb_state_get_event_info(
event_name: *const std::os::raw::c_char,
event_id: *mut std::os::raw::c_int,
event_id: *mut u8,
event_type: *mut AppLayerEventType,
) -> std::os::raw::c_int {
SMBEvent::get_event_info(event_name, event_id, event_type)
Expand Down
22 changes: 8 additions & 14 deletions src/app-layer-dnp3.c
Original file line number Diff line number Diff line change
Expand Up @@ -1435,27 +1435,21 @@ static int DNP3GetAlstateProgress(void *tx, uint8_t direction)
/**
* \brief App-layer support.
*/
static int DNP3StateGetEventInfo(const char *event_name, int *event_id,
AppLayerEventType *event_type)
static int DNP3StateGetEventInfo(
const char *event_name, uint8_t *event_id, AppLayerEventType *event_type)
{
*event_id = SCMapEnumNameToValue(event_name, dnp3_decoder_event_table);
if (*event_id == -1) {
SCLogError("Event \"%s\" not present in "
"the DNP3 enum event map table.",
event_name);
return -1;
if (SCAppLayerGetEventIdByName(event_name, dnp3_decoder_event_table, event_id) == 0) {
*event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
return 0;
}

*event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;

return 0;
return -1;
}

/**
* \brief App-layer support.
*/
static int DNP3StateGetEventInfoById(int event_id, const char **event_name,
AppLayerEventType *event_type)
static int DNP3StateGetEventInfoById(
uint8_t event_id, const char **event_name, AppLayerEventType *event_type)
{
*event_name = SCMapEnumValueToName(event_id, dnp3_decoder_event_table);
if (*event_name == NULL) {
Expand Down
52 changes: 27 additions & 25 deletions src/app-layer-events.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2014-2022 Open Information Security Foundation
/* Copyright (C) 2014-2024 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
Expand Down Expand Up @@ -29,6 +29,22 @@
#include "app-layer-parser.h"
#include "util-enum.h"

int SCAppLayerGetEventIdByName(const char *event_name, SCEnumCharMap *table, uint8_t *event_id)
{
int value = SCMapEnumNameToValue(event_name, table);
if (value == -1) {
SCLogError("event \"%s\" not present in enum table.", event_name);
/* this should be treated as fatal */
return -1;
} else if (value < -1 || value > UINT8_MAX) {
SCLogError("event \"%s\" has out of range value", event_name);
/* this should be treated as fatal */
return -1;
}
*event_id = (uint8_t)value;
return 0;
}

/* events raised during protocol detection are stored in the
* packets storage, not in the flow. */
SCEnumCharMap app_layer_event_pkt_table[ ] = {
Expand All @@ -48,8 +64,8 @@ SCEnumCharMap app_layer_event_pkt_table[ ] = {
-1 },
};

int AppLayerGetEventInfoById(int event_id, const char **event_name,
AppLayerEventType *event_type)
int AppLayerGetEventInfoById(
uint8_t event_id, const char **event_name, AppLayerEventType *event_type)
{
*event_name = SCMapEnumValueToName(event_id, app_layer_event_pkt_table);
if (*event_name == NULL) {
Expand All @@ -65,18 +81,9 @@ int AppLayerGetEventInfoById(int event_id, const char **event_name,
return 0;
}

int AppLayerGetPktEventInfo(const char *event_name, int *event_id)
int AppLayerGetPktEventInfo(const char *event_name, uint8_t *event_id)
{
*event_id = SCMapEnumNameToValue(event_name, app_layer_event_pkt_table);
if (*event_id == -1) {
SCLogError("event \"%s\" not present in "
"app-layer-event's packet event table.",
event_name);
/* this should be treated as fatal */
return -1;
}

return 0;
return SCAppLayerGetEventIdByName(event_name, app_layer_event_pkt_table, event_id);
}

#define DECODER_EVENTS_BUFFER_STEPS 8
Expand Down Expand Up @@ -161,17 +168,12 @@ SCEnumCharMap det_ctx_event_table[] = {
{ NULL, -1 },
};

int DetectEngineGetEventInfo(const char *event_name, int *event_id, AppLayerEventType *event_type)
int DetectEngineGetEventInfo(
const char *event_name, uint8_t *event_id, AppLayerEventType *event_type)
{
*event_id = SCMapEnumNameToValue(event_name, det_ctx_event_table);
if (*event_id == -1) {
SCLogError("event \"%s\" not present in "
"det_ctx's enum map table.",
event_name);
/* this should be treated as fatal */
return -1;
if (SCAppLayerGetEventIdByName(event_name, det_ctx_event_table, event_id) == 0) {
*event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
return 0;
}
*event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;

return 0;
return -1;
}
11 changes: 7 additions & 4 deletions src/app-layer-events.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
/* contains fwd declaration of AppLayerDecoderEvents_ */
#include "decode.h"
#include "rust.h"
#include "util-enum.h"

/**
* \brief Data structure to store app layer decoder events.
Expand All @@ -53,10 +54,10 @@ enum {
APPLAYER_UNEXPECTED_PROTOCOL,
};

int AppLayerGetPktEventInfo(const char *event_name, int *event_id);
int AppLayerGetPktEventInfo(const char *event_name, uint8_t *event_id);

int AppLayerGetEventInfoById(int event_id, const char **event_name,
AppLayerEventType *event_type);
int AppLayerGetEventInfoById(
uint8_t event_id, const char **event_name, AppLayerEventType *event_type);
void AppLayerDecoderEventsSetEventRaw(AppLayerDecoderEvents **sevents, uint8_t event);

static inline int AppLayerDecoderEventsIsEventSet(
Expand All @@ -76,6 +77,8 @@ static inline int AppLayerDecoderEventsIsEventSet(

void AppLayerDecoderEventsResetEvents(AppLayerDecoderEvents *events);
void AppLayerDecoderEventsFreeEvents(AppLayerDecoderEvents **events);
int DetectEngineGetEventInfo(const char *event_name, int *event_id, AppLayerEventType *event_type);
int DetectEngineGetEventInfo(
const char *event_name, uint8_t *event_id, AppLayerEventType *event_type);
int SCAppLayerGetEventIdByName(const char *event_name, SCEnumCharMap *table, uint8_t *event_id);

#endif /* SURICATA_APP_LAYER_EVENTS_H */
23 changes: 8 additions & 15 deletions src/app-layer-htp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2718,25 +2718,18 @@ void *HtpGetTxForH2(void *alstate)
return NULL;
}

static int HTPStateGetEventInfo(const char *event_name,
int *event_id, AppLayerEventType *event_type)
static int HTPStateGetEventInfo(
const char *event_name, uint8_t *event_id, AppLayerEventType *event_type)
{
*event_id = SCMapEnumNameToValue(event_name, http_decoder_event_table);
if (*event_id == -1) {
SCLogError("event \"%s\" not present in "
"http's enum map table.",
event_name);
/* this should be treated as fatal */
return -1;
if (SCAppLayerGetEventIdByName(event_name, http_decoder_event_table, event_id) == 0) {
*event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
return 0;
}

*event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;

return 0;
return -1;
}

static int HTPStateGetEventInfoById(int event_id, const char **event_name,
AppLayerEventType *event_type)
static int HTPStateGetEventInfoById(
uint8_t event_id, const char **event_name, AppLayerEventType *event_type)
{
*event_name = SCMapEnumValueToName(event_id, http_decoder_event_table);
if (*event_name == NULL) {
Expand Down
22 changes: 11 additions & 11 deletions src/app-layer-parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ typedef struct AppLayerParserProtoCtx_
AppLayerGetTxIteratorFunc StateGetTxIterator;
int complete_ts;
int complete_tc;
int (*StateGetEventInfoById)(int event_id, const char **event_name,
AppLayerEventType *event_type);
int (*StateGetEventInfo)(const char *event_name,
int *event_id, AppLayerEventType *event_type);
int (*StateGetEventInfoById)(
uint8_t event_id, const char **event_name, AppLayerEventType *event_type);
int (*StateGetEventInfo)(
const char *event_name, uint8_t *event_id, AppLayerEventType *event_type);

AppLayerStateData *(*GetStateData)(void *state);
AppLayerTxData *(*GetTxData)(void *tx);
Expand Down Expand Up @@ -531,8 +531,8 @@ void AppLayerParserRegisterStateProgressCompletionStatus(
}

void AppLayerParserRegisterGetEventInfoById(uint8_t ipproto, AppProto alproto,
int (*StateGetEventInfoById)(int event_id, const char **event_name,
AppLayerEventType *event_type))
int (*StateGetEventInfoById)(
uint8_t event_id, const char **event_name, AppLayerEventType *event_type))
{
SCEnter();

Expand All @@ -553,8 +553,8 @@ void AppLayerParserRegisterGetFrameFuncs(uint8_t ipproto, AppProto alproto,
}

void AppLayerParserRegisterGetEventInfo(uint8_t ipproto, AppProto alproto,
int (*StateGetEventInfo)(const char *event_name, int *event_id,
AppLayerEventType *event_type))
int (*StateGetEventInfo)(
const char *event_name, uint8_t *event_id, AppLayerEventType *event_type))
{
SCEnter();

Expand Down Expand Up @@ -1100,7 +1100,7 @@ int AppLayerParserGetStateProgressCompletionStatus(AppProto alproto,
}

int AppLayerParserGetEventInfo(uint8_t ipproto, AppProto alproto, const char *event_name,
int *event_id, AppLayerEventType *event_type)
uint8_t *event_id, AppLayerEventType *event_type)
{
SCEnter();
const int ipproto_map = FlowGetProtoMapping(ipproto);
Expand All @@ -1109,8 +1109,8 @@ int AppLayerParserGetEventInfo(uint8_t ipproto, AppProto alproto, const char *ev
SCReturnInt(r);
}

int AppLayerParserGetEventInfoById(uint8_t ipproto, AppProto alproto, int event_id,
const char **event_name, AppLayerEventType *event_type)
int AppLayerParserGetEventInfoById(uint8_t ipproto, AppProto alproto, uint8_t event_id,
const char **event_name, AppLayerEventType *event_type)
{
SCEnter();
const int ipproto_map = FlowGetProtoMapping(ipproto);
Expand Down
Loading

0 comments on commit b1e6031

Please sign in to comment.