From bc5c9f4a52b4924e7a816e99d928a9df0e7f7653 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sun, 2 Oct 2011 01:16:07 +0200 Subject: [PATCH] Fix too many SMTP commands causing an integer overflow in the cmds_cnt variable, in turn causing an out of bounds memory write. --- src/app-layer-smtp.c | 14 ++++++++++++-- src/app-layer-smtp.h | 16 ++++++++-------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/app-layer-smtp.c b/src/app-layer-smtp.c index 80a2399492..f118377593 100644 --- a/src/app-layer-smtp.c +++ b/src/app-layer-smtp.c @@ -297,14 +297,19 @@ static int SMTPGetLine(SMTPState *state) static int SMTPInsertCommandIntoCommandBuffer(uint8_t command, SMTPState *state) { if (state->cmds_cnt >= state->cmds_buffer_len) { + int increment = SMTP_COMMAND_BUFFER_STEPS; + if ((int)(state->cmds_buffer_len + SMTP_COMMAND_BUFFER_STEPS) > (int)USHRT_MAX) { + increment = USHRT_MAX - state->cmds_buffer_len; + } + state->cmds = SCRealloc(state->cmds, sizeof(uint8_t) * (state->cmds_buffer_len + - SMTP_COMMAND_BUFFER_STEPS)); + increment)); if (state->cmds == NULL) { return -1; } - state->cmds_buffer_len += SMTP_COMMAND_BUFFER_STEPS; + state->cmds_buffer_len += increment; } if (state->cmds_cnt >= 1 && ((state->cmds[state->cmds_cnt - 1] == SMTP_COMMAND_STARTTLS) || @@ -313,6 +318,11 @@ static int SMTPInsertCommandIntoCommandBuffer(uint8_t command, SMTPState *state) /* we have to have EHLO, DATA, VRFY, EXPN, TURN, QUIT, NOOP, * STARTTLS as the last command in pipelined mode */ } + + /** \todo decoder event */ + if ((int)(state->cmds_cnt + 1) > (int)USHRT_MAX) + return -1; + state->cmds[state->cmds_cnt] = command; state->cmds_cnt++; diff --git a/src/app-layer-smtp.h b/src/app-layer-smtp.h index e4d61cb70b..62315fa31f 100644 --- a/src/app-layer-smtp.h +++ b/src/app-layer-smtp.h @@ -59,15 +59,15 @@ typedef struct SMTPState_ { /* the request commands are store here and the reply handler uses these * stored command in the buffer to match the reply(ies) with the command */ - /* the command buffer */ + /** the command buffer */ uint8_t *cmds; - /* the buffer length */ - uint8_t cmds_buffer_len; - /* no of commands stored in the above buffer */ - uint8_t cmds_cnt; - /* index of the command in the buffer, currently in inspection by reply - * handler */ - uint8_t cmds_idx; + /** the buffer length */ + uint16_t cmds_buffer_len; + /** no of commands stored in the above buffer */ + uint16_t cmds_cnt; + /** index of the command in the buffer, currently in inspection by reply + * handler */ + uint16_t cmds_idx; } SMTPState; void RegisterSMTPParsers(void);