]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
app-layer: split EOF flag per direction
authorVictor Julien <victor@inliniac.net>
Tue, 16 Jun 2020 08:23:49 +0000 (10:23 +0200)
committerVictor Julien <victor@inliniac.net>
Tue, 28 Jul 2020 09:34:32 +0000 (11:34 +0200)
13 files changed:
src/app-layer-enip.c
src/app-layer-ftp.c
src/app-layer-htp.c
src/app-layer-modbus.c
src/app-layer-parser.c
src/app-layer-parser.h
src/app-layer-smtp.c
src/app-layer-ssl.c
src/app-layer-template.c
src/app-layer-tftp.c
src/flow-timeout.c
src/output-tx.c
src/tests/fuzz/fuzz_applayerparserparse.c

index f6bf4503092b7b824d2dc2364662f96e60667e55..52c6c5dab39865927782c6e3162251b80fac30f6 100644 (file)
@@ -327,7 +327,7 @@ static AppLayerResult ENIPParse(Flow *f, void *state, AppLayerParserState *pstat
     ENIPTransaction *tx;
 
     if (input == NULL && AppLayerParserStateIssetFlag(pstate,
-            APP_LAYER_PARSER_EOF))
+            APP_LAYER_PARSER_EOF_TS|APP_LAYER_PARSER_EOF_TC))
     {
         SCReturnStruct(APP_LAYER_OK);
     } else if (input == NULL && input_len != 0) {
index 2810475d2b897085e4f0ca884f6b74c54f815e47..1a3e91cb2750a30881bdba71afb7b11c67b9bfca 100644 (file)
@@ -559,7 +559,7 @@ static AppLayerResult FTPParseRequest(Flow *f, void *ftp_state,
     FtpState *state = (FtpState *)ftp_state;
     void *ptmp;
 
-    if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+    if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS)) {
         SCReturnStruct(APP_LAYER_OK);
     } else if (input == NULL || input_len == 0) {
         SCReturnStruct(APP_LAYER_ERROR);
@@ -1113,7 +1113,10 @@ static AppLayerResult FTPDataParse(Flow *f, FtpDataState *ftpdata_state,
         }
     }
 
-    if (input_len && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+    const bool eof_flag = flags & STREAM_TOSERVER ?
+        AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS) != 0 :
+        AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC) != 0;
+    if (input_len && eof_flag) {
         ret = FileCloseFile(ftpdata_state->files, (uint8_t *) NULL, 0, flags);
         ftpdata_state->state = FTPDATA_STATE_FINISHED;
     }
index 9d8e163d87ec315451888b65fb8957c23e689a89..e19d2bf758ff3ac1cd1837839646c474ae186e7b 100644 (file)
@@ -897,7 +897,7 @@ static AppLayerResult HTPHandleRequestData(Flow *f, void *htp_state,
     }
 
     /* if the TCP connection is closed, then close the HTTP connection */
-    if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF) &&
+    if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS) &&
         !(hstate->flags & HTP_FLAG_STATE_CLOSED_TS))
     {
         htp_connp_req_close(hstate->connp, &ts);
@@ -960,7 +960,7 @@ static AppLayerResult HTPHandleResponseData(Flow *f, void *htp_state,
     }
 
     /* if we the TCP connection is closed, then close the HTTP connection */
-    if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF) &&
+    if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC) &&
         !(hstate->flags & HTP_FLAG_STATE_CLOSED_TC))
     {
         htp_connp_close(hstate->connp, &ts);
index 3aecf25ceba4ec0db338fef94b8dacdac6119330..f5908e7fc9bb2da46d7e34a7930cdc4e18925b41 100644 (file)
@@ -1274,7 +1274,7 @@ static AppLayerResult ModbusParseRequest(Flow       *f,
     ModbusTransaction   *tx;
     ModbusHeader        header;
 
-    if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+    if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS)) {
         SCReturnStruct(APP_LAYER_OK);
     } else if (input == NULL || input_len == 0) {
         SCReturnStruct(APP_LAYER_ERROR);
@@ -1339,7 +1339,7 @@ static AppLayerResult ModbusParseResponse(Flow      *f,
     ModbusState         *modbus = (ModbusState *) state;
     ModbusTransaction   *tx;
 
-    if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+    if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC)) {
         SCReturnStruct(APP_LAYER_OK);
     } else if (input == NULL || input_len == 0) {
         SCReturnStruct(APP_LAYER_ERROR);
index 22636d6fc146eb49580a360feaef45ec51ced77b..0be1ab07e1d27d6c6ccb638d52e7c766474fe997 100644 (file)
@@ -1160,6 +1160,17 @@ void AppLayerParserApplyTxConfig(uint8_t ipproto, AppProto alproto,
 
 /***** General *****/
 
+static inline void SetEOFFlags(AppLayerParserState *pstate, const uint8_t flags)
+{
+    if ((flags & (STREAM_EOF|STREAM_TOSERVER)) == (STREAM_EOF|STREAM_TOSERVER)) {
+        SCLogDebug("setting APP_LAYER_PARSER_EOF_TS");
+        AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF_TS);
+    } else if ((flags & (STREAM_EOF|STREAM_TOCLIENT)) == (STREAM_EOF|STREAM_TOCLIENT)) {
+        SCLogDebug("setting APP_LAYER_PARSER_EOF_TC");
+        AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF_TC);
+    }
+}
+
 /** \retval int -1 in case of unrecoverable error. App-layer tracking stops for this flow.
  *  \retval int 0 ok: we did not update app_progress
  *  \retval int 1 ok: we updated app_progress */
@@ -1199,8 +1210,7 @@ int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow
             goto error;
     }
 
-    if (flags & STREAM_EOF)
-        AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF);
+    SetEOFFlags(pstate, flags);
 
     alstate = f->alstate;
     if (alstate == NULL) {
@@ -1333,7 +1343,7 @@ void AppLayerParserSetEOF(AppLayerParserState *pstate)
     if (pstate == NULL)
         goto end;
 
-    AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF);
+    AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF_TS|APP_LAYER_PARSER_EOF_TC);
 
  end:
     SCReturn;
index 85623d3a4e230293604b6ae773fb51c01115e3b8..19201d6a4ec56a30891fd2e1933b2bc05b082285 100644 (file)
 #include "util-config.h"
 
 /* Flags for AppLayerParserState. */
-#define APP_LAYER_PARSER_EOF                    BIT_U8(0)
+// flag available                               BIT_U8(0)
 #define APP_LAYER_PARSER_NO_INSPECTION          BIT_U8(1)
 #define APP_LAYER_PARSER_NO_REASSEMBLY          BIT_U8(2)
 #define APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD  BIT_U8(3)
 #define APP_LAYER_PARSER_BYPASS_READY           BIT_U8(4)
+#define APP_LAYER_PARSER_EOF_TS                 BIT_U8(5)
+#define APP_LAYER_PARSER_EOF_TC                 BIT_U8(6)
 
 /* Flags for AppLayerParserProtoCtx. */
 #define APP_LAYER_PARSER_OPT_ACCEPT_GAPS        BIT_U32(0)
index 49685cbddfd8d3b25857b8a3ffa572417d7b7329..2de623d34a5a15e41e20d23624d1852044f5b91b 100644 (file)
@@ -1376,7 +1376,9 @@ static AppLayerResult SMTPParse(int direction, Flow *f, SMTPState *state,
 {
     SCEnter();
 
-    if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+    if (input == NULL &&
+            ((direction == 0 && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS)) ||
+             (direction == 1 && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC)))) {
         SCReturnStruct(APP_LAYER_OK);
     } else if (input == NULL || input_len == 0) {
         SCReturnStruct(APP_LAYER_ERROR);
index 82163af8f7cf969581206dda49fb8652ceb3bcfe..557253058ea9192a3288100fb00984cc0e8224dd 100644 (file)
@@ -2501,7 +2501,8 @@ static AppLayerResult SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLa
     ssl_state->f = f;
 
     if (input == NULL &&
-            AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+            ((direction == 0 && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS)) ||
+             (direction == 1 && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC)))) {
         /* flag session as finished if APP_LAYER_PARSER_EOF is set */
         ssl_state->flags |= SSL_AL_FLAG_STATE_FINISHED;
         SCReturnStruct(APP_LAYER_OK);
@@ -2606,7 +2607,8 @@ static AppLayerResult SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLa
     }
 
     /* flag session as finished if APP_LAYER_PARSER_EOF is set */
-    if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+    if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS) &&
+        AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC)) {
         SCLogDebug("SSL_AL_FLAG_STATE_FINISHED");
         ssl_state->flags |= SSL_AL_FLAG_STATE_FINISHED;
     }
index 198fb432beca3f19a3d9dec96175a3f45b4388ab..83eab5fa3d87cbc636eb50ef1b7e611f332d28f4 100644 (file)
@@ -246,7 +246,7 @@ static AppLayerResult TemplateParseRequest(Flow *f, void *statev,
     SCLogNotice("Parsing template request: len=%"PRIu32, input_len);
 
     if (input == NULL) {
-        if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+        if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS)) {
             /* This is a signal that the stream is done. Do any
              * cleanup if needed. Usually nothing is required here. */
             SCReturnStruct(APP_LAYER_OK);
@@ -322,7 +322,7 @@ static AppLayerResult TemplateParseResponse(Flow *f, void *statev, AppLayerParse
 
     /* Likely connection closed, we can just return here. */
     if ((input == NULL || input_len == 0) &&
-        AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+        AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC)) {
         SCReturnStruct(APP_LAYER_OK);
     }
 
index 821f91bc7ca94b07804f7825f25bca7ccc6edea3..f5ec69e7f6d60240832d80e0132d66ac74aeb3e8 100644 (file)
@@ -104,7 +104,7 @@ static AppLayerResult TFTPParseRequest(Flow *f, void *state,
 
     /* Likely connection closed, we can just return here. */
     if ((input == NULL || input_len == 0) &&
-        AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+        AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS)) {
         SCReturnStruct(APP_LAYER_OK);
     }
 
index c5dafb06f8e6b175f71bc7be8f8ffbc789099c17..f21f3fe9eb6ae14617cf8039d4c489770c1ec56f 100644 (file)
@@ -248,8 +248,6 @@ static inline Packet *FlowForceReassemblyPseudoPacketSetup(Packet *p,
     memset(&p->ts, 0, sizeof(struct timeval));
     TimeGet(&p->ts);
 
-    AppLayerParserSetEOF(f->alparser);
-
     return p;
 
 error:
index 5974168890cd6ca48d8e3185ec745eef20b83f99..4294d40f4cf286f67e470cd12c5966dea5d40598 100644 (file)
@@ -260,8 +260,15 @@ static TmEcode OutputTxLog(ThreadVars *tv, Packet *p, void *thread_data)
             if ((tx_logged_old & (1<<logger->logger_id)) == 0) {
                 SCLogDebug("alproto match %d, logging tx_id %"PRIu64, logger->alproto, tx_id);
 
-                if (!(AppLayerParserStateIssetFlag(f->alparser,
-                                                   APP_LAYER_PARSER_EOF))) {
+                const bool ts_eof = AppLayerParserStateIssetFlag(f->alparser,
+                        APP_LAYER_PARSER_EOF_TS) != 0;
+                const bool tc_eof = AppLayerParserStateIssetFlag(f->alparser,
+                        APP_LAYER_PARSER_EOF_TC) != 0;
+                SCLogDebug("pcap_cnt %"PRIu64", tx_id %"PRIu64" logger %d. EOFs TS %s TC %s",
+                        p->pcap_cnt, tx_id, logger->logger_id,
+                        ts_eof ? "true" : "false", tc_eof ? "true" : "false");
+
+                if (!(ts_eof && tc_eof)) {
                     if (logger->LogCondition) {
                         int r = logger->LogCondition(tv, p, alstate, tx, tx_id);
                         if (r == FALSE) {
index ae9beaaf8c35f7bc7ca38c0b4fc12fa025c094f1..c319c22223d6866358137419acad22539644f12e 100644 (file)
@@ -125,7 +125,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
             (void) AppLayerParserParse(NULL, alp_tctx, f, f->alproto, flags, isolatedBuffer, alnext - albuffer);
             free(isolatedBuffer);
             flags &= ~(STREAM_START);
-            if (f->alparser && AppLayerParserStateIssetFlag(f->alparser, APP_LAYER_PARSER_EOF)) {
+            if (f->alparser &&
+                   (((flags & STREAM_TOSERVER) != 0 &&
+                     AppLayerParserStateIssetFlag(f->alparser, APP_LAYER_PARSER_EOF_TS)) ||
+                    ((flags & STREAM_TOCLIENT) != 0 &&
+                     AppLayerParserStateIssetFlag(f->alparser, APP_LAYER_PARSER_EOF_TC)))) {
                 //no final chunk
                 alsize = 0;
                 break;