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.

(cherry picked from commit ab6dcb3)

Additional fixup for ENIP that was no in master.
  • Loading branch information
jasonish committed Nov 1, 2024
1 parent 3000e96 commit b1bc752
Show file tree
Hide file tree
Showing 16 changed files with 123 additions and 155 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, *mut c_void, u8) -> AppLayerGetFileState;
Expand Down Expand Up @@ -566,7 +566,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 @@ -575,16 +575,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 @@ -608,27 +608,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 @@ -2226,7 +2226,7 @@ pub unsafe extern "C" fn rs_smb_state_truncate(

#[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 @@ -2236,7 +2236,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 @@ -1443,27 +1443,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
23 changes: 8 additions & 15 deletions src/app-layer-enip.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,25 +103,18 @@ static uint64_t ENIPGetTxCnt(void *alstate)
return ((ENIPState *)alstate)->transaction_max;
}

static int ENIPStateGetEventInfo(const char *event_name, int *event_id, AppLayerEventType *event_type)
static int ENIPStateGetEventInfo(
const char *event_name, uint8_t *event_id, AppLayerEventType *event_type)
{
*event_id = SCMapEnumNameToValue(event_name, enip_decoder_event_table);

if (*event_id == -1) {
SCLogError("event \"%s\" not present in "
"enip's enum map table.",
event_name);
/* yes this is fatal */
return -1;
if (SCAppLayerGetEventIdByName(event_name, enip_decoder_event_table, event_id)) {
*event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
return 0;
}

*event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;

return 0;
return -1;
}

static int ENIPStateGetEventInfoById(int event_id, const char **event_name,
AppLayerEventType *event_type)
static int ENIPStateGetEventInfoById(
uint8_t event_id, const char **event_name, AppLayerEventType *event_type)
{
*event_name = SCMapEnumValueToName(event_id, enip_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 @@ -162,17 +169,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(AppLayerDecoderEvents *devents,
Expand All @@ -77,7 +78,9 @@ static inline int AppLayerDecoderEventsIsEventSet(AppLayerDecoderEvents *devents

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 /* __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 @@ -3144,25 +3144,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
Loading

0 comments on commit b1bc752

Please sign in to comment.