From: Philippe Antoine Date: Tue, 31 May 2022 11:24:09 +0000 (+0200) Subject: ftp: remove temporary fields from state X-Git-Tag: suricata-7.0.0-beta1~522 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5a00acece2c681dd590e7a02ae8ead6cdcd1229b;p=thirdparty%2Fsuricata.git ftp: remove temporary fields from state As input, input_len and direction only last for the scope of one call of AppLayerParserParse, it is not necessary to keep them in FtpState which lives longer, so we consume less memory. --- diff --git a/src/app-layer-ftp.c b/src/app-layer-ftp.c index 79a7836af6..92f9bfef41 100644 --- a/src/app-layer-ftp.c +++ b/src/app-layer-ftp.c @@ -369,7 +369,12 @@ static void FTPTransactionFree(FTPTransaction *tx) FTPFree(tx, sizeof(*tx)); } -static int FTPGetLineForDirection(FtpState *state, FtpLineState *line_state) +typedef struct FtpInput_ { + const uint8_t *input; + int32_t input_len; +} FtpInput; + +static int FTPGetLineForDirection(FtpState *state, FtpLineState *line_state, FtpInput *ftpi) { void *ptmp; if (line_state->current_line_lf_seen == 1) { @@ -388,9 +393,9 @@ static int FTPGetLineForDirection(FtpState *state, FtpLineState *line_state) } /* Should be guaranteed by the caller. */ - DEBUG_VALIDATE_BUG_ON(state->input_len <= 0); + DEBUG_VALIDATE_BUG_ON(ftpi->input_len <= 0); - uint8_t *lf_idx = memchr(state->input, 0x0a, state->input_len); + uint8_t *lf_idx = memchr(ftpi->input, 0x0a, ftpi->input_len); if (lf_idx == NULL) { /* fragmented lines. Decoder event for special cases. Not all @@ -400,7 +405,7 @@ static int FTPGetLineForDirection(FtpState *state, FtpLineState *line_state) * if we see fragmentation then it's definitely something you * should alert about */ if (line_state->current_line_db == 0) { - int32_t input_len = state->input_len; + int32_t input_len = ftpi->input_len; if ((uint32_t)input_len > ftp_max_line_len) { input_len = ftp_max_line_len; state->current_line_truncated = true; @@ -410,10 +415,10 @@ static int FTPGetLineForDirection(FtpState *state, FtpLineState *line_state) return -1; } line_state->current_line_db = 1; - memcpy(line_state->db, state->input, input_len); + memcpy(line_state->db, ftpi->input, input_len); line_state->db_len = input_len; } else if (!state->current_line_truncated) { - int32_t input_len = state->input_len; + int32_t input_len = ftpi->input_len; if (line_state->db_len + input_len > ftp_max_line_len) { input_len = ftp_max_line_len - line_state->db_len; DEBUG_VALIDATE_BUG_ON(input_len < 0); @@ -430,12 +435,12 @@ static int FTPGetLineForDirection(FtpState *state, FtpLineState *line_state) } line_state->db = ptmp; - memcpy(line_state->db + line_state->db_len, state->input, input_len); + memcpy(line_state->db + line_state->db_len, ftpi->input, input_len); line_state->db_len += input_len; } } - state->input += state->input_len; - state->input_len = 0; + ftpi->input += ftpi->input_len; + ftpi->input_len = 0; return -1; @@ -444,7 +449,7 @@ static int FTPGetLineForDirection(FtpState *state, FtpLineState *line_state) if (line_state->current_line_db == 1) { if (!state->current_line_truncated) { - int32_t input_len = lf_idx + 1 - state->input; + int32_t input_len = lf_idx + 1 - ftpi->input; if (line_state->db_len + input_len > ftp_max_line_len) { input_len = ftp_max_line_len - line_state->db_len; DEBUG_VALIDATE_BUG_ON(input_len < 0); @@ -461,7 +466,7 @@ static int FTPGetLineForDirection(FtpState *state, FtpLineState *line_state) } line_state->db = ptmp; - memcpy(line_state->db + line_state->db_len, state->input, input_len); + memcpy(line_state->db + line_state->db_len, ftpi->input, input_len); line_state->db_len += input_len; if (line_state->db_len > 1 && line_state->db[line_state->db_len - 2] == 0x0D) { @@ -478,16 +483,15 @@ static int FTPGetLineForDirection(FtpState *state, FtpLineState *line_state) state->current_line_len = line_state->db_len; } else { - state->current_line = state->input; - if (lf_idx - state->input > ftp_max_line_len) { + state->current_line = ftpi->input; + if (lf_idx - ftpi->input > ftp_max_line_len) { state->current_line_len = ftp_max_line_len; state->current_line_truncated = true; } else { - state->current_line_len = lf_idx - state->input; + state->current_line_len = lf_idx - ftpi->input; } - if (state->input != lf_idx && - *(lf_idx - 1) == 0x0D) { + if (ftpi->input != lf_idx && *(lf_idx - 1) == 0x0D) { state->current_line_len--; state->current_line_delimiter_len = 2; } else { @@ -495,27 +499,27 @@ static int FTPGetLineForDirection(FtpState *state, FtpLineState *line_state) } } - state->input_len -= (lf_idx - state->input) + 1; - state->input = (lf_idx + 1); + ftpi->input_len -= (lf_idx - ftpi->input) + 1; + ftpi->input = (lf_idx + 1); return 0; } } -static int FTPGetLine(FtpState *state) +static int FTPGetLine(FtpState *state, int direction, FtpInput *ftpi) { SCEnter(); /* we have run out of input */ - if (state->input_len <= 0) + if (ftpi->input_len <= 0) return -1; /* toserver */ - if (state->direction == 0) - return FTPGetLineForDirection(state, &state->line_state[0]); + if (direction == STREAM_TOSERVER) + return FTPGetLineForDirection(state, &state->line_state[0], ftpi); else - return FTPGetLineForDirection(state, &state->line_state[1]); + return FTPGetLineForDirection(state, &state->line_state[1], ftpi); } /** @@ -619,13 +623,10 @@ static AppLayerResult FTPParseRequest(Flow *f, void *ftp_state, AppLayerParserSt SCReturnStruct(APP_LAYER_ERROR); } - state->input = input; - state->input_len = input_len; - /* toserver stream */ - state->direction = 0; + FtpInput ftpi = { .input = input, .input_len = input_len }; int direction = STREAM_TOSERVER; - while (FTPGetLine(state) >= 0) { + while (FTPGetLine(state, STREAM_TOSERVER, &ftpi) >= 0) { const FtpCommand *cmd_descriptor; if (!FTPParseRequestCommand(thread_data, @@ -802,13 +803,10 @@ static AppLayerResult FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserS if (unlikely(input_len == 0)) { SCReturnStruct(APP_LAYER_OK); } - state->input = input; - state->input_len = input_len; - /* toclient stream */ - state->direction = 1; + FtpInput ftpi = { .input = input, .input_len = input_len }; FTPTransaction *lasttx = TAILQ_FIRST(&state->tx_list); - while (FTPGetLine(state) >= 0) { + while (FTPGetLine(state, STREAM_TOCLIENT, &ftpi) >= 0) { FTPTransaction *tx = FTPGetOldestTx(state, lasttx); if (tx == NULL) { tx = FTPTransactionCreate(state); diff --git a/src/app-layer-ftp.h b/src/app-layer-ftp.h index 09762c5848..7e8b4ad553 100644 --- a/src/app-layer-ftp.h +++ b/src/app-layer-ftp.h @@ -160,9 +160,6 @@ typedef struct FTPTransaction_ { /** FTP State for app layer parser */ typedef struct FtpState_ { - const uint8_t *input; - int32_t input_len; - uint8_t direction; bool active; FTPTransaction *curr_tx;