]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
http: fail tx creation if we cannot allocate user data 13073/head
authorPhilippe Antoine <pantoine@oisf.net>
Fri, 18 Apr 2025 19:16:29 +0000 (21:16 +0200)
committerVictor Julien <victor@inliniac.net>
Tue, 22 Apr 2025 10:22:40 +0000 (12:22 +0200)
So, we always have a libhtp.rs htp_tx_t and a Suricata tx
with its AppLayerTxData

Thus AppLayerParserGetTxData cannot return NULL

Ticket: 5739

22 files changed:
rust/htp/src/c_api/config.rs
rust/htp/src/c_api/transaction.rs
rust/htp/src/config.rs
rust/htp/src/hook.rs
rust/htp/src/transaction.rs
rust/htp/src/transactions.rs
src/app-layer-htp.c
src/app-layer-parser.c
src/detect-config.c
src/detect-engine-state.c
src/detect-filestore.c
src/detect-http-client-body.c
src/detect-http-header.c
src/detect-http-raw-header.c
src/detect-xbits.c
src/detect.c
src/output-filedata.c
src/output-json-http.c
src/output-streaming.c
src/output-tx.c
src/util-file.c
src/util-lua-http.c

index 0b85b7c2ed562c4aacd2fd8fa6f8758e4dc4a5dc..e3c9110c77017f5f06b218eb9a9cd46ad2873b27 100644 (file)
@@ -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
index 6c0fc9b00bd06136cca4f61f2241e4151c3be8c5..9830b6183fe515e085b97a4f6bf577ec5b0e2369 100644 (file)
@@ -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.
index fc629652aa0900a6802166b8734b08062eaa5416..d165cb98d2d7c6d41d96061560e3a0d3ded0f3cf 100644 (file)
@@ -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(),
index 29d02c027b9cb59f4fd8eed7cf68aba35ced0f8a..a9a598cc7b5730528990e28ba44fe8190b767c60 100644 (file)
@@ -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;
index fd60c7b14501c61edf5b45ba9e38570dbe651256..146192d0fd1e79dbfb27467f5ec6a6e6b22b3bfa 100644 (file)
@@ -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?
index 0b7e527c97d8438f0c958b46a604b9db6cdd84cd..1b2aba9becbe3998938b4b14324909e83c05ca1b 100644 (file)
@@ -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
             }
         }
     }
index b6de7baa78d6f619bb3ccfb8f685cf309bdde8c6..4f6e5b9d48eb12a843478f2df61b2838d3bce384 100644 (file)
@@ -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)
index 5b2b6198603a09816d8de627957425af12708755..9139b73db8f8ca50c3b73c1902f7258220f2a0ca 100644 (file)
@@ -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);
index d700e5d0f9649115b412bffdf1ee7dfc582b9e52..c1f0e103409cc734316aadb94e57323af3d7382b 100644 (file)
@@ -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");
index c1552ab893ad635fc10cec6d24dfc4016db7abc8..f887cbfb36e54a44f5ec66a760408bcf1cfecea6 100644 (file)
@@ -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)
index e93dcceabd9c9b73ecacd6246d77d75ad67984c4..d281bbf2a151e9babf069862e8e26c8d0b64246e 100644 (file)
@@ -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 */
index 2504f67fd8e0a1d8854e8bbbf0f2f822a8da5c4f..35f8b976e977753a26b704f566362c5740667bed 100644 (file)
@@ -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;
 }
 
index 5a7536f819f3ea94a29b5b957319600727521107..094375f42e83d5ea3c273029c0e0108d605b5cd4 100644 (file)
@@ -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);
index 8adc67be4a0c82ee15cf0e8d0ffd66af9b89d490..0b4adef6fa62374c007fdd1b683de644ffb136d0 100644 (file)
@@ -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);
index 50f88144f4f9226ebee2ad40e9b97a4046af2913..ca24ca4738c2bb95ef25f2ba191e3d7e9383baa0 100644 (file)
@@ -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);
index d662e66e999487c0fd445596cae29a52bc2de302..d0da67757816d7a254b1a8bb33a4eeb19d1871a3 100644 (file)
@@ -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)) {
index fdff2d97810f21feb88d80fe36dd52f83699b885..476ab18a583e8f27d775ece5fc987466d5e90cd8 100644 (file)
@@ -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;
 }
 
index adf5234daf094f589c0a6423be2f7721695de8ee..95ca0cbdecee71b08c5b52f2b25456ffffe9ebc0 100644 (file)
@@ -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");
         }
     }
 }
index 8f2f65ab20e01641935c9f4dcbcedb62cc694ed3..51906dc9dd0c51590a9e92120ab34bbba05769c2 100644 (file)
@@ -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;
 }
index a4da9d5e2fbf1341479df16a08ad6a40796c8284..9bc08ad45cfeff0dfd2b27af70d3a550b17a74e1 100644 (file)
@@ -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);
index fe1b4e7684f9343639e175dfce03448003f11ca8..8fc8998bc7d3e17a699d77d60cf7df5cf9f0d631 100644 (file)
@@ -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;
         }
     }
 }
index f92a706ac487b2dd9e9ba569858540dd2100dc74..7849f4ae525c43583db5a32e69dc20ef2d29b709 100644 (file)
@@ -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)