]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
ftp: truncate first segment if over max length 7377/head
authorJason Ish <jason.ish@oisf.net>
Fri, 22 Apr 2022 18:04:37 +0000 (12:04 -0600)
committerVictor Julien <vjulien@oisf.net>
Wed, 4 May 2022 21:08:14 +0000 (23:08 +0200)
The first segment was not limited to the configured maximum line length
allowing it to be up to 65k. This could result in the next input length
being negative, which while handled properly by the code, did trigger a
debug validation assertion.

The fix is to be consistent and apply the limit to the first segment as
well, which does ensure the input_len could never be less than 0.

Ticket #5281

(cherry picked from commit 9645285dff9eb8313db573d8603162a708736236)

src/app-layer-ftp.c

index d201238632efaf54091b2542ebc79eecb62415e8..7d6d989b7e69f2a71a573ad8d58f11f79582b419 100644 (file)
@@ -376,6 +376,9 @@ static int FTPGetLineForDirection(FtpState *state, FtpLineState *line_state)
         }
     }
 
+    /* Should be guaranteed by the caller. */
+    DEBUG_VALIDATE_BUG_ON(state->input_len <= 0);
+
     uint8_t *lf_idx = memchr(state->input, 0x0a, state->input_len);
 
     if (lf_idx == NULL) {
@@ -386,13 +389,18 @@ 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) {
-            line_state->db = FTPMalloc(state->input_len);
+            int32_t input_len = state->input_len;
+            if ((uint32_t)input_len > ftp_max_line_len) {
+                input_len = ftp_max_line_len;
+                state->current_line_truncated = true;
+            }
+            line_state->db = FTPMalloc(input_len);
             if (line_state->db == NULL) {
                 return -1;
             }
             line_state->current_line_db = 1;
-            memcpy(line_state->db, state->input, state->input_len);
-            line_state->db_len = state->input_len;
+            memcpy(line_state->db, state->input, input_len);
+            line_state->db_len = input_len;
         } else if (!state->current_line_truncated) {
             int32_t input_len = state->input_len;
             if (line_state->db_len + input_len > ftp_max_line_len) {