http: fail tx creation if we cannot allocate user data

So, we always have a libhtp.rs htp_tx_t and a Suricata tx
with its AppLayerTxData

Thus AppLayerParserGetTxData cannot return NULL

Ticket: 5739
pull/13073/head
Philippe Antoine 3 months ago committed by Victor Julien
parent 0167001ce8
commit 833a738dd1

@ -1,7 +1,7 @@
#![deny(missing_docs)]
use crate::{
config::{Config, HtpServerPersonality, HtpUrlEncodingHandling},
hook::{DataExternalCallbackFn, TxExternalCallbackFn},
hook::{DataExternalCallbackFn, TxCreateCallbackFn, TxDestroyCallbackFn, TxExternalCallbackFn},
HtpStatus,
};
use std::convert::TryInto;
@ -74,6 +74,31 @@ pub unsafe extern "C" fn htp_config_register_request_line(
}
}
/// Registers a tx create callback, which is invoked every time a new
/// request begins and before any parsing is done.
/// # Safety
/// When calling this method, you have to ensure that cfg is either properly initialized or NULL
#[no_mangle]
pub unsafe extern "C" fn htp_config_register_tx_create(
cfg: *mut Config, cbk_fn: TxCreateCallbackFn,
) {
if let Some(cfg) = cfg.as_mut() {
cfg.hook_tx_create = Some(cbk_fn);
}
}
/// Registers a tx destroy callback, which is invoked every time a tx is dropped
/// # Safety
/// When calling this method, you have to ensure that cfg is either properly initialized or NULL
#[no_mangle]
pub unsafe extern "C" fn htp_config_register_tx_destroy(
cfg: *mut Config, cbk_fn: TxDestroyCallbackFn,
) {
if let Some(cfg) = cfg.as_mut() {
cfg.hook_tx_destroy = Some(cbk_fn);
}
}
/// Registers a REQUEST_START callback, which is invoked every time a new
/// request begins and before any parsing is done.
/// # Safety

@ -45,16 +45,6 @@ pub unsafe extern "C" fn htp_tx_get_user_data(tx: *const Transaction) -> *mut li
.unwrap_or(std::ptr::null_mut())
}
/// Associates user data with this transaction.
/// # Safety
/// When calling this method, you have to ensure that tx is either properly initialized or NULL
#[no_mangle]
pub unsafe extern "C" fn htp_tx_set_user_data(tx: *mut Transaction, user_data: *mut libc::c_void) {
if let Some(tx) = tx.as_mut() {
tx.set_user_data(Box::new(user_data))
}
}
/// Get a transaction's request line.
///
/// tx: Transaction pointer.

@ -6,6 +6,8 @@ use crate::{
HtpStatus,
};
use crate::hook::{TxCreateCallbackFn, TxDestroyCallbackFn};
#[cfg(test)]
use crate::hook::{DataNativeCallbackFn, TxNativeCallbackFn};
@ -20,6 +22,14 @@ pub struct Config {
pub(crate) server_personality: HtpServerPersonality,
/// Decoder configuration for url path.
pub(crate) decoder_cfg: DecoderConfig,
/// Transaction creation hook.
/// Used by suricata to allocate its transaction (user data)
/// And make libhtp.rs tx creation fail (return None) if suricata failed
/// to do the C allocation.
pub(crate) hook_tx_create: Option<TxCreateCallbackFn>,
/// Transaction destroy hook.
/// Used by suricata to free its transaction (user data)
pub(crate) hook_tx_destroy: Option<TxDestroyCallbackFn>,
/// Request start hook, invoked when the parser receives the first byte of a new
/// request. Because an HTTP transaction always starts with a request, this hook
/// doubles as a transaction start hook.
@ -104,6 +114,8 @@ impl Default for Config {
field_limit: 18000,
server_personality: HtpServerPersonality::MINIMAL,
decoder_cfg: Default::default(),
hook_tx_create: None,
hook_tx_destroy: None,
hook_request_start: TxHook::default(),
hook_request_line: TxHook::default(),
hook_request_header_data: DataHook::default(),

@ -15,6 +15,12 @@ pub(crate) type TxNativeCallbackFn = fn(tx: &mut Transaction) -> Result<()>;
/// Hook for Transaction
pub(crate) type TxHook = Hook<TxExternalCallbackFn, TxNativeCallbackFn>;
/// External (C) callback function prototype
pub(crate) type TxCreateCallbackFn = unsafe extern "C" fn(req: bool) -> *mut libc::c_void;
/// External (C) callback function prototype
pub(crate) type TxDestroyCallbackFn = unsafe extern "C" fn(tx_ud: *mut libc::c_void);
/// External (C) callback function prototype
pub(crate) type DataExternalCallbackFn =
unsafe extern "C" fn(connp: *const ConnectionParser, data: *mut Data) -> HtpStatus;

@ -1,5 +1,6 @@
use crate::{
bstr::Bstr,
c_api::transaction::htp_tx_get_user_data,
config::{Config, HtpUnwanted},
connection_parser::ParserData,
decompressors::{Decompressor, HtpContentEncoding},
@ -598,10 +599,23 @@ impl std::fmt::Debug for Transaction {
}
}
impl Drop for Transaction {
fn drop(&mut self) {
if self.user_data.is_none() {
return;
}
if let Some(cb) = self.cfg.hook_tx_destroy {
unsafe { cb(htp_tx_get_user_data(self)) };
}
}
}
impl Transaction {
/// Construct a new transaction.
pub(crate) fn new(cfg: &'static Config, logger: &Logger, index: usize) -> Self {
Self {
pub(crate) fn new(
cfg: &'static Config, logger: &Logger, index: usize, req: bool,
) -> Option<Self> {
let mut tx = Self {
logger: logger.clone(),
cfg,
user_data: None,
@ -661,7 +675,15 @@ impl Transaction {
response_header_repetitions: 0,
request_header_parser: HeaderParser::new(Side::Request),
response_header_parser: HeaderParser::new(Side::Response),
};
if let Some(cb) = cfg.hook_tx_create {
let r = unsafe { cb(req) };
if r.is_null() {
return None;
}
tx.set_user_data(Box::new(r));
}
Some(tx)
}
/// Has this transaction started?

@ -67,7 +67,11 @@ impl Transactions {
if nbtx >= cfg.max_tx as usize {
return None;
}
Some(entry.insert(Transaction::new(cfg, logger, request)))
let tx = Transaction::new(cfg, logger, request, true);
if let Some(tx) = tx {
return Some(entry.insert(tx));
}
None
}
}
}
@ -97,7 +101,11 @@ impl Transactions {
if nbtx >= cfg.max_tx as usize {
return None;
}
Some(entry.insert(Transaction::new(cfg, logger, response)))
let tx = Transaction::new(cfg, logger, response, false);
if let Some(tx) = tx {
return Some(entry.insert(tx));
}
None
}
}
}

@ -439,11 +439,9 @@ static void HTPSetEvent(HtpState *s, HtpTxUserData *htud,
tx = HTPStateGetTx(s, tx_id - 1);
if (tx != NULL) {
htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (htud != NULL) {
AppLayerDecoderEventsSetEventRaw(&htud->tx_data.events, e);
s->events++;
return;
}
AppLayerDecoderEventsSetEventRaw(&htud->tx_data.events, e);
s->events++;
return;
}
SCLogDebug("couldn't set event %u", e);
}
@ -473,8 +471,9 @@ static void *HTPStateAlloc(void *orig_state, AppProto proto_orig)
SCReturnPtr((void *)s, "void");
}
static void HtpTxUserDataFree(HtpState *state, HtpTxUserData *htud)
static void HtpTxUserDataFree(void *txud)
{
HtpTxUserData *htud = (HtpTxUserData *)txud;
if (likely(htud)) {
HtpBodyFree(&htud->request_body);
HtpBodyFree(&htud->response_body);
@ -510,20 +509,6 @@ void HTPStateFree(void *state)
/* free the connection parser memory used by HTP library */
if (s->connp != NULL) {
SCLogDebug("freeing HTP state");
uint64_t tx_id;
uint64_t total_txs = HTPStateGetTxCnt(state);
/* free the list of body chunks */
if (s->conn != NULL) {
for (tx_id = 0; tx_id < total_txs; tx_id++) {
htp_tx_t *tx = HTPStateGetTx(s, tx_id);
if (tx != NULL) {
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
HtpTxUserDataFree(s, htud);
htp_tx_set_user_data(tx, NULL);
}
}
}
htp_connp_destroy_all(s->connp);
}
@ -554,10 +539,6 @@ static void HTPStateTransactionFree(void *state, uint64_t id)
htp_tx_t *tx = HTPStateGetTx(s, id);
if (tx != NULL) {
/* This will remove obsolete body chunks */
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
HtpTxUserDataFree(s, htud);
htp_tx_set_user_data(tx, NULL);
htp_tx_destroy(s->connp, tx);
}
}
@ -607,13 +588,11 @@ void AppLayerHtpNeedFileInspection(void)
static void AppLayerHtpSetStreamDepthFlag(void *tx, const uint8_t flags)
{
HtpTxUserData *tx_ud = (HtpTxUserData *)htp_tx_get_user_data((htp_tx_t *)tx);
if (tx_ud) {
SCLogDebug("setting HTP_STREAM_DEPTH_SET, flags %02x", flags);
if (flags & STREAM_TOCLIENT) {
tx_ud->tcflags |= HTP_STREAM_DEPTH_SET;
} else {
tx_ud->tsflags |= HTP_STREAM_DEPTH_SET;
}
SCLogDebug("setting HTP_STREAM_DEPTH_SET, flags %02x", flags);
if (flags & STREAM_TOCLIENT) {
tx_ud->tcflags |= HTP_STREAM_DEPTH_SET;
} else {
tx_ud->tsflags |= HTP_STREAM_DEPTH_SET;
}
}
@ -709,8 +688,6 @@ static inline void HTPErrorCheckTxRequestFlags(HtpState *s, const htp_tx_t *tx)
HTP_FLAGS_HOST_MISSING | HTP_FLAGS_HOST_AMBIGUOUS |
HTP_FLAGS_HOSTU_INVALID | HTP_FLAGS_HOSTH_INVALID)) {
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (htud == NULL)
return;
if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_T_E)
HTPSetEvent(s, htud, STREAM_TOSERVER,
@ -729,16 +706,12 @@ static inline void HTPErrorCheckTxRequestFlags(HtpState *s, const htp_tx_t *tx)
}
if (htp_tx_request_auth_type(tx) == HTP_AUTH_TYPE_UNRECOGNIZED) {
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (htud == NULL)
return;
HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_AUTH_UNRECOGNIZED);
}
if (htp_tx_is_protocol_0_9(tx) && htp_tx_request_method_number(tx) == HTP_METHOD_UNKNOWN &&
(htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_INVALID ||
htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_UNKNOWN)) {
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (htud == NULL)
return;
HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_REQUEST_LINE_INVALID);
}
}
@ -1539,9 +1512,6 @@ static int HTPCallbackResponseBodyData(const htp_connp_t *connp, htp_tx_data_t *
hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d));
HtpTxUserData *tx_ud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (tx_ud == NULL) {
SCReturnInt(HTP_STATUS_OK);
}
tx_ud->tx_data.updated_tc = true;
SCTxDataUpdateFileFlags(&tx_ud->tx_data, hstate->state_data.file_flags);
if (!tx_ud->request_body_init) {
@ -1650,23 +1620,34 @@ void HTPFreeConfig(void)
static int HTPCallbackRequestHasTrailer(const htp_connp_t *connp, htp_tx_t *tx)
{
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (htud != NULL) {
htud->tx_data.updated_ts = true;
htud->request_has_trailers = 1;
}
htud->tx_data.updated_ts = true;
htud->request_has_trailers = 1;
return HTP_STATUS_OK;
}
static int HTPCallbackResponseHasTrailer(const htp_connp_t *connp, htp_tx_t *tx)
{
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (htud != NULL) {
htud->tx_data.updated_tc = true;
htud->response_has_trailers = 1;
}
htud->tx_data.updated_tc = true;
htud->response_has_trailers = 1;
return HTP_STATUS_OK;
}
static void *HTPCallbackTxCreate(bool request)
{
HtpTxUserData *tx_ud = HTPCalloc(1, sizeof(HtpTxUserData));
if (unlikely(tx_ud == NULL)) {
return NULL;
}
if (request) {
// each http tx may xfer files
tx_ud->tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT;
} else {
tx_ud->tx_data.file_tx = STREAM_TOCLIENT; // Toserver already missed.
}
return tx_ud;
}
/**\internal
* \brief called at start of request
* Set min inspect size.
@ -1696,14 +1677,6 @@ static int HTPCallbackRequestStart(const htp_connp_t *connp, htp_tx_t *tx)
hstate->cfg->request.inspect_min_size);
HtpTxUserData *tx_ud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (tx_ud == NULL) {
tx_ud = HTPCalloc(1, sizeof(HtpTxUserData));
if (unlikely(tx_ud == NULL)) {
SCReturnInt(HTP_STATUS_OK);
}
tx_ud->tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT; // each http tx may xfer files
htp_tx_set_user_data(tx, tx_ud);
}
tx_ud->tx_data.updated_ts = true;
SCReturnInt(HTP_STATUS_OK);
}
@ -1736,15 +1709,6 @@ static int HTPCallbackResponseStart(const htp_connp_t *connp, htp_tx_t *tx)
hstate->cfg->response.inspect_min_size);
HtpTxUserData *tx_ud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (tx_ud == NULL) {
tx_ud = HTPCalloc(1, sizeof(HtpTxUserData));
if (unlikely(tx_ud == NULL)) {
SCReturnInt(HTP_STATUS_OK);
}
tx_ud->tx_data.file_tx =
STREAM_TOCLIENT; // each http tx may xfer files. Toserver already missed.
htp_tx_set_user_data(tx, tx_ud);
}
tx_ud->tx_data.updated_tc = true;
SCReturnInt(HTP_STATUS_OK);
}
@ -1795,16 +1759,14 @@ static int HTPCallbackRequestComplete(const htp_connp_t *connp, htp_tx_t *tx)
HTPErrorCheckTxRequestFlags(hstate, tx);
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (htud != NULL) {
htud->tx_data.updated_ts = true;
if (htud->tsflags & HTP_FILENAME_SET) {
SCLogDebug("closing file that was being stored");
(void)HTPFileClose(htud, NULL, 0, 0, STREAM_TOSERVER);
htud->tsflags &= ~HTP_FILENAME_SET;
if (abs_right_edge < (uint64_t)UINT32_MAX) {
StreamTcpReassemblySetMinInspectDepth(
hstate->f->protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
}
htud->tx_data.updated_ts = true;
if (htud->tsflags & HTP_FILENAME_SET) {
SCLogDebug("closing file that was being stored");
(void)HTPFileClose(htud, NULL, 0, 0, STREAM_TOSERVER);
htud->tsflags &= ~HTP_FILENAME_SET;
if (abs_right_edge < (uint64_t)UINT32_MAX) {
StreamTcpReassemblySetMinInspectDepth(
hstate->f->protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
}
}
@ -1851,13 +1813,11 @@ static int HTPCallbackResponseComplete(const htp_connp_t *connp, htp_tx_t *tx)
}
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (htud != NULL) {
htud->tx_data.updated_tc = true;
if (htud->tcflags & HTP_FILENAME_SET) {
SCLogDebug("closing file that was being stored");
(void)HTPFileClose(htud, NULL, 0, 0, STREAM_TOCLIENT);
htud->tcflags &= ~HTP_FILENAME_SET;
}
htud->tx_data.updated_tc = true;
if (htud->tcflags & HTP_FILENAME_SET) {
SCLogDebug("closing file that was being stored");
(void)HTPFileClose(htud, NULL, 0, 0, STREAM_TOCLIENT);
htud->tcflags &= ~HTP_FILENAME_SET;
}
/* response done, do raw reassembly now to inspect state and stream
@ -1888,14 +1848,8 @@ static int HTPCallbackResponseComplete(const htp_connp_t *connp, htp_tx_t *tx)
static int HTPCallbackRequestLine(const htp_connp_t *connp, htp_tx_t *tx)
{
HtpTxUserData *tx_ud;
HtpState *hstate = htp_connp_user_data(connp);
tx_ud = htp_tx_get_user_data(tx);
if (unlikely(tx_ud == NULL)) {
return HTP_STATUS_OK;
}
if (htp_tx_flags(tx)) {
HTPErrorCheckTxRequestFlags(hstate, tx);
}
@ -1910,9 +1864,6 @@ static int HTPCallbackRequestHeaderData(const htp_connp_t *connp, htp_tx_data_t
return HTP_STATUS_OK;
HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
if (tx_ud == NULL) {
return HTP_STATUS_OK;
}
ptmp = HTPRealloc(tx_ud->request_headers_raw, tx_ud->request_headers_raw_len,
tx_ud->request_headers_raw_len + htp_tx_data_len(tx_data));
if (ptmp == NULL) {
@ -1940,9 +1891,6 @@ static int HTPCallbackResponseHeaderData(const htp_connp_t *connp, htp_tx_data_t
return HTP_STATUS_OK;
HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
if (tx_ud == NULL) {
return HTP_STATUS_OK;
}
tx_ud->tx_data.updated_tc = true;
ptmp = HTPRealloc(tx_ud->response_headers_raw, tx_ud->response_headers_raw_len,
tx_ud->response_headers_raw_len + htp_tx_data_len(tx_data));
@ -1989,6 +1937,9 @@ static void HTPConfigSetDefaultsPhase1(HTPCfgRec *cfg_prec)
htp_config_register_request_body_data(cfg_prec->cfg, HTPCallbackRequestBodyData);
htp_config_register_response_body_data(cfg_prec->cfg, HTPCallbackResponseBodyData);
htp_config_register_tx_create(cfg_prec->cfg, HTPCallbackTxCreate);
htp_config_register_tx_destroy(cfg_prec->cfg, HtpTxUserDataFree);
htp_config_register_request_start(cfg_prec->cfg, HTPCallbackRequestStart);
htp_config_register_request_complete(cfg_prec->cfg, HTPCallbackRequestComplete);
@ -2494,12 +2445,10 @@ static AppLayerGetFileState HTPGetTxFiles(void *txv, uint8_t direction)
AppLayerGetFileState files = { .fc = NULL, .cfg = &htp_sbcfg };
htp_tx_t *tx = (htp_tx_t *)txv;
HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
if (tx_ud) {
if (direction & STREAM_TOCLIENT) {
files.fc = &tx_ud->files_tc;
} else {
files.fc = &tx_ud->files_ts;
}
if (direction & STREAM_TOCLIENT) {
files.fc = &tx_ud->files_tc;
} else {
files.fc = &tx_ud->files_ts;
}
return files;
}
@ -2581,10 +2530,7 @@ static AppLayerTxData *HTPGetTxData(void *vtx)
{
htp_tx_t *tx = (htp_tx_t *)vtx;
HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
if (tx_ud) {
return &tx_ud->tx_data;
}
return NULL;
return &tx_ud->tx_data;
}
static AppLayerStateData *HTPGetStateData(void *vstate)

@ -784,7 +784,7 @@ void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *p
break;
AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx);
if (txd && tag_txs_as_inspected) {
if (tag_txs_as_inspected) {
const uint8_t inspected_flag = (flags & STREAM_TOSERVER) ? APP_LAYER_TX_INSPECTED_TS
: APP_LAYER_TX_INSPECTED_TC;
if (txd->flags & inspected_flag) {
@ -824,22 +824,16 @@ void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *p
/* txd can be NULL for HTTP sessions where the user data alloc failed */
AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx);
if (likely(txd)) {
const uint8_t inspected_flag = (flags & STREAM_TOSERVER)
? APP_LAYER_TX_INSPECTED_TS
: APP_LAYER_TX_INSPECTED_TC;
if (txd->flags & inspected_flag) {
txd->flags |= inspected_flag;
SCLogDebug("%p/%" PRIu64 " out of order tx is done for direction %s. Flag %02x",
tx, idx, flags & STREAM_TOSERVER ? "toserver" : "toclient", txd->flags);
SCLogDebug("%p/%"PRIu64" out of order tx. Update inspect_id? %"PRIu64,
tx, idx, pstate->inspect_id[direction]);
if (pstate->inspect_id[direction]+1 == idx)
pstate->inspect_id[direction] = idx;
}
} else {
if (pstate->inspect_id[direction]+1 == idx)
const uint8_t inspected_flag = (flags & STREAM_TOSERVER) ? APP_LAYER_TX_INSPECTED_TS
: APP_LAYER_TX_INSPECTED_TC;
if (txd->flags & inspected_flag) {
txd->flags |= inspected_flag;
SCLogDebug("%p/%" PRIu64 " out of order tx is done for direction %s. Flag %02x", tx,
idx, flags & STREAM_TOSERVER ? "toserver" : "toclient", txd->flags);
SCLogDebug("%p/%" PRIu64 " out of order tx. Update inspect_id? %" PRIu64, tx, idx,
pstate->inspect_id[direction]);
if (pstate->inspect_id[direction] + 1 == idx)
pstate->inspect_id[direction] = idx;
}
if (!ires.has_next)
@ -868,7 +862,7 @@ AppLayerDecoderEvents *AppLayerParserGetEventsByTx(uint8_t ipproto, AppProto alp
/* Access events via the tx_data. */
AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx);
if (txd != NULL && txd->events != NULL) {
if (txd->events != NULL) {
ptr = txd->events;
}
@ -953,7 +947,7 @@ void AppLayerParserTransactionsCleanup(Flow *f, const uint8_t pkt_dir)
SCLogDebug("%p/%"PRIu64" checking", tx, i);
AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx);
if (txd != NULL && AppLayerParserHasFilesInDir(txd, pkt_dir)) {
if (AppLayerParserHasFilesInDir(txd, pkt_dir)) {
if (pkt_dir_trunc == -1)
pkt_dir_trunc = IS_DISRUPTED(
(pkt_dir == STREAM_TOSERVER) ? ts_disrupt_flags : tc_disrupt_flags);

@ -94,23 +94,18 @@ static void ConfigApplyTx(Flow *f,
void *tx = AppLayerParserGetTx(f->proto, f->alproto, f->alstate, tx_id);
if (tx) {
AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, tx);
if (txd) {
SCLogDebug("tx %p txd %p: log_flags %x", tx, txd, txd->config.log_flags);
txd->config.log_flags |= BIT_U8(config->type);
const bool unidir =
(txd->flags & (APP_LAYER_TX_SKIP_INSPECT_TS | APP_LAYER_TX_SKIP_INSPECT_TC)) !=
0;
if (unidir) {
SCLogDebug("handle unidir tx");
AppLayerTxConfig req;
memset(&req, 0, sizeof(req));
req.log_flags = BIT_U8(config->type);
AppLayerParserApplyTxConfig(
f->proto, f->alproto, f->alstate, tx, CONFIG_ACTION_SET, req);
}
} else {
SCLogDebug("no tx data");
SCLogDebug("tx %p txd %p: log_flags %x", tx, txd, txd->config.log_flags);
txd->config.log_flags |= BIT_U8(config->type);
const bool unidir =
(txd->flags & (APP_LAYER_TX_SKIP_INSPECT_TS | APP_LAYER_TX_SKIP_INSPECT_TC)) != 0;
if (unidir) {
SCLogDebug("handle unidir tx");
AppLayerTxConfig req;
memset(&req, 0, sizeof(req));
req.log_flags = BIT_U8(config->type);
AppLayerParserApplyTxConfig(
f->proto, f->alproto, f->alstate, tx, CONFIG_ACTION_SET, req);
}
} else {
SCLogDebug("no tx");

@ -219,11 +219,6 @@ void DetectRunStoreStateTx(
const uint16_t file_no_match)
{
AppLayerTxData *tx_data = AppLayerParserGetTxData(f->proto, f->alproto, tx);
BUG_ON(tx_data == NULL);
if (tx_data == NULL) {
SCLogDebug("No TX data for %" PRIu64, tx_id);
return;
}
if (tx_data->de_state == NULL) {
tx_data->de_state = DetectEngineStateAlloc();
if (tx_data->de_state == NULL)

@ -159,15 +159,12 @@ static int FilestorePostMatchWithOptions(Packet *p, Flow *f, const DetectFilesto
DEBUG_VALIDATE_BUG_ON(txv == NULL);
if (txv != NULL) {
AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, txv);
DEBUG_VALIDATE_BUG_ON(txd == NULL);
if (txd != NULL) {
if (toclient_dir) {
txd->file_flags |= FLOWFILE_STORE_TC;
}
if (toclient_dir) {
txd->file_flags |= FLOWFILE_STORE_TC;
}
if (toserver_dir) {
txd->file_flags |= FLOWFILE_STORE_TS;
}
}
}
} else if (this_flow) {
/* set in flow and AppLayerStateData */

@ -182,11 +182,6 @@ static int DetectHttpClientBodySetupSticky(DetectEngineCtx *de_ctx, Signature *s
static inline HtpBody *GetRequestBody(htp_tx_t *tx)
{
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (htud == NULL) {
SCLogDebug("no htud");
return NULL;
}
return &htud->request_body;
}

@ -274,9 +274,8 @@ static void PrefilterMpmHttpTrailer(DetectEngineThreadCtx *det_ctx, const void *
htp_tx_t *tx = txv;
const HtpTxUserData *htud = (const HtpTxUserData *)htp_tx_get_user_data(tx);
/* if the request wasn't flagged as having a trailer, we skip */
if (htud && (
((flags & STREAM_TOSERVER) && !htud->request_has_trailers) ||
((flags & STREAM_TOCLIENT) && !htud->response_has_trailers))) {
if (((flags & STREAM_TOSERVER) && !htud->request_has_trailers) ||
((flags & STREAM_TOCLIENT) && !htud->response_has_trailers)) {
SCReturn;
}
PrefilterMpmHttpHeader(det_ctx, pectx, p, f, txv, idx, _txd, flags);

@ -191,8 +191,6 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
htp_tx_t *tx = (htp_tx_t *)txv;
HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
if (tx_ud == NULL)
return NULL;
const bool ts = ((flow_flags & STREAM_TOSERVER) != 0);
const uint8_t *data = ts ?
@ -280,9 +278,8 @@ static void PrefilterMpmHttpTrailerRaw(DetectEngineThreadCtx *det_ctx, const voi
htp_tx_t *tx = txv;
const HtpTxUserData *htud = (const HtpTxUserData *)htp_tx_get_user_data(tx);
/* if the request wasn't flagged as having a trailer, we skip */
if (htud && (
((flags & STREAM_TOSERVER) && !htud->request_has_trailers) ||
((flags & STREAM_TOCLIENT) && !htud->response_has_trailers))) {
if (((flags & STREAM_TOSERVER) && !htud->request_has_trailers) ||
((flags & STREAM_TOCLIENT) && !htud->response_has_trailers)) {
SCReturn;
}
PrefilterMpmHttpHeaderRaw(det_ctx, pectx, p, f, txv, idx, _txd, flags);

@ -224,9 +224,6 @@ static int DetectXbitTxMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t fl
BUG_ON(xd == NULL);
AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, txv);
if (txd == NULL) {
return 0;
}
SCLogDebug("sid:%u: tx:%" PRIu64 ", txd->txbits:%p", s->id, det_ctx->tx_id, txd->txbits);
int r = TxBitIsset(txd, xd->idx);

@ -590,9 +590,8 @@ static bool IsOnlyTxInDirection(Flow *f, uint64_t txid, uint8_t dir)
if (tx) {
AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, tx);
// test if the other tx is unidirectional in the other way
if (txd && ((dir == STREAM_TOSERVER && (txd->flags & APP_LAYER_TX_SKIP_INSPECT_TS)) ||
(dir == STREAM_TOCLIENT &&
(txd->flags & APP_LAYER_TX_SKIP_INSPECT_TC)))) {
if ((dir == STREAM_TOSERVER && (txd->flags & APP_LAYER_TX_SKIP_INSPECT_TS)) ||
(dir == STREAM_TOCLIENT && (txd->flags & APP_LAYER_TX_SKIP_INSPECT_TC))) {
return true;
}
}
@ -1358,10 +1357,6 @@ static DetectTransaction GetDetectTx(const uint8_t ipproto, const AppProto alpro
const uint64_t tx_id, void *tx_ptr, const int tx_end_state, const uint8_t flow_flags)
{
AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx_ptr);
if (unlikely(txd == NULL)) {
DetectTransaction no_tx = NO_TX;
return no_tx;
}
const int tx_progress = AppLayerParserGetStateProgress(ipproto, alproto, tx_ptr, flow_flags);
bool updated = (flow_flags & STREAM_TOSERVER) ? txd->updated_ts : txd->updated_tc;
if (!updated && tx_progress < tx_end_state && ((flow_flags & STREAM_EOF) == 0)) {

@ -114,10 +114,8 @@ static void CloseFile(const Packet *p, Flow *f, File *file, void *txv)
DEBUG_VALIDATE_BUG_ON((file->flags & FILE_STORED) != 0);
AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, txv);
if (txd) {
BUG_ON(f->alproto == ALPROTO_SMB && txd->files_logged != 0);
txd->files_stored++;
}
BUG_ON(f->alproto == ALPROTO_SMB && txd->files_logged != 0);
txd->files_stored++;
file->flags |= FILE_STORED;
}

@ -395,10 +395,8 @@ void EveHttpLogJSONBodyPrintable(SCJsonBuilder *js, Flow *f, uint64_t tx_id)
htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, tx_id);
if (tx) {
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (htud != NULL) {
BodyPrintableBuffer(js, &htud->request_body, "http_request_body_printable");
BodyPrintableBuffer(js, &htud->response_body, "http_response_body_printable");
}
BodyPrintableBuffer(js, &htud->request_body, "http_request_body_printable");
BodyPrintableBuffer(js, &htud->response_body, "http_response_body_printable");
}
}
}
@ -426,10 +424,8 @@ void EveHttpLogJSONBodyBase64(SCJsonBuilder *js, Flow *f, uint64_t tx_id)
htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, tx_id);
if (tx) {
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (htud != NULL) {
BodyBase64Buffer(js, &htud->request_body, "http_request_body");
BodyBase64Buffer(js, &htud->response_body, "http_response_body");
}
BodyBase64Buffer(js, &htud->request_body, "http_request_body");
BodyBase64Buffer(js, &htud->response_body, "http_response_body");
}
}
}

@ -178,19 +178,18 @@ static int HttpBodyIterator(Flow *f, int close, void *cbdata, uint8_t iflags)
}
SCLogDebug("tx %p", tx);
HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx);
if (htud != NULL) {
SCLogDebug("htud %p", htud);
HtpBody *body = NULL;
if (iflags & OUTPUT_STREAMING_FLAG_TOSERVER)
body = &htud->request_body;
else if (iflags & OUTPUT_STREAMING_FLAG_TOCLIENT)
body = &htud->response_body;
if (body == NULL) {
SCLogDebug("no body");
goto next;
}
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
SCLogDebug("htud %p", htud);
HtpBody *body = NULL;
if (iflags & OUTPUT_STREAMING_FLAG_TOSERVER)
body = &htud->request_body;
else if (iflags & OUTPUT_STREAMING_FLAG_TOCLIENT)
body = &htud->response_body;
if (body == NULL) {
SCLogDebug("no body");
goto next;
}
if (body->first == NULL) {
SCLogDebug("no body chunks");
goto next;
@ -236,7 +235,6 @@ static int HttpBodyIterator(Flow *f, int close, void *cbdata, uint8_t iflags)
Streamer(cbdata, f, NULL, 0, tx_id,
iflags|OUTPUT_STREAMING_FLAG_CLOSE|OUTPUT_STREAMING_FLAG_TRANSACTION);
}
}
}
return 0;
}

@ -416,13 +416,6 @@ static TmEcode OutputTxLog(ThreadVars *tv, Packet *p, void *thread_data)
SCLogDebug("STARTING tx_id %" PRIu64 ", tx %p", tx_id, tx);
AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx);
if (unlikely(txd == NULL)) {
SCLogDebug("NO TXD");
/* make sure this tx, which can't be properly logged is skipped */
logged = 1;
max_id = tx_id;
goto next_tx;
}
const int tx_progress_ts =
AppLayerParserGetStateProgress(ipproto, alproto, tx, ts_disrupt_flags);

@ -1157,12 +1157,10 @@ void FileDisableStoringForTransaction(Flow *f, const uint8_t direction, void *tx
{
if (g_file_force_filestore == 0) {
AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, tx);
if (txd != NULL) {
if (direction & STREAM_TOSERVER) {
txd->file_flags |= FLOWFILE_NO_STORE_TS;
} else {
txd->file_flags |= FLOWFILE_NO_STORE_TC;
}
if (direction & STREAM_TOSERVER) {
txd->file_flags |= FLOWFILE_NO_STORE_TS;
} else {
txd->file_flags |= FLOWFILE_NO_STORE_TC;
}
}
}

@ -169,8 +169,6 @@ static int LuaHttpGetRawHeaders(lua_State *luastate, int dir)
return 1;
}
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx->tx);
if (htud == NULL)
return LuaCallbackError(luastate, "no htud in tx");
uint8_t *raw = htud->request_headers_raw;
uint32_t raw_len = htud->request_headers_raw_len;
@ -245,8 +243,6 @@ static int LuaHttpGetBody(lua_State *luastate, int dir)
}
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx->tx);
if (htud == NULL)
return LuaCallbackError(luastate, "no htud in tx");
HtpBody *body = NULL;
if (dir == 0)

Loading…
Cancel
Save