ftp: a too-long line drops the rest of the stream slice

Both parse loops stopped as soon as a command or reply reached the
configured maximum length: they advanced the input cursor past the end and
broke out. When that line ended with an LF in the same stream slice it was
already complete, and the bytes behind the LF were ordinary FTP lines that
the break discarded. A segment holding "PORT <long>\r\nQUIT\r\n" lost the
QUIT: it never became a transaction, so inspection and logging never saw
it, and a hidden RETR or PORT never reached AppLayerExpectationCreate,
leaving its data connection unrecognized as ftp-data.

Remove both breaks so the loop continues to the next line. The cursor
assignment goes with them, since nothing reads it once the loop ends, and a
line with no LF still finishes the slice on its own because the getter
zeroes the remaining length.

Removing the breaks is not enough for a line that never reaches the clear.
Truncation was cleared deep inside command and reply handling, which is
skipped for an unrecognized request command, a reply the parser rejects (a
run of spaces, empty once trimmed), or an invalid EPRT/PORT that jumps to
tx_complete. The connection flag then stayed set and the getter dropped the
line behind it as this line's remainder. Snapshot and clear the flag up
front in both loops, for every line whose LF was consumed, so the following
line survives.

Issue: 8884
pull/16213/head
Jeff Lucovsky 2 months ago committed by Philippe Antoine
parent 368bfa6d1f
commit 46fce26900

@ -613,10 +613,6 @@ static AppLayerResult FTPParseRequest(Flow *f, void *ftp_state, AppLayerParserSt
default:
break;
}
if (line.len >= ftp_max_line_len) {
ftpi.consumed = ftpi.len + 1;
break;
}
SCAppLayerParserTriggerRawStreamInspection(f, STREAM_TOSERVER);
}
@ -718,6 +714,7 @@ static AppLayerResult FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserS
}
state->curr_tx = tx;
uint16_t dyn_port;
switch (state->command) {
case FTP_COMMAND_AUTH_TLS:
@ -791,11 +788,6 @@ static AppLayerResult FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserS
tx_complete:
tx->done = true;
SCAppLayerParserTriggerRawStreamInspection(f, STREAM_TOCLIENT);
if (line.len >= ftp_max_line_len) {
ftpi.consumed = ftpi.len + 1;
break;
}
}
SCReturnStruct(APP_LAYER_OK);

Loading…
Cancel
Save