diff --git a/src/suricata-common.h b/src/suricata-common.h index 753d1f5522d..f9655eaccc3 100644 --- a/src/suricata-common.h +++ b/src/suricata-common.h @@ -501,5 +501,9 @@ extern int g_ut_covered; #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) +#ifndef NAME_MAX +#define NAME_MAX 255 +#endif + #endif /* __SURICATA_COMMON_H__ */ diff --git a/src/util-decode-mime.c b/src/util-decode-mime.c index 7dbc814d378..24dee93debe 100644 --- a/src/util-decode-mime.c +++ b/src/util-decode-mime.c @@ -1,4 +1,5 @@ /* Copyright (C) 2012 BAE Systems + * Copyright (C) 2020 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -1830,30 +1831,62 @@ static int FindMimeHeader(const uint8_t *buf, uint32_t blen, * \param search_start The start of the search (ie. boundary=\") * \param search_end The end of the search (ie. \") * \param tlen The output length of the token (if found) + * \param max_len The maximum offset in which to search * * \return A pointer to the token if found, otherwise NULL if not found */ -static uint8_t * FindMimeHeaderToken(MimeDecField *field, const char *search_start, - const char *search_end, uint32_t *tlen) +static uint8_t * FindMimeHeaderTokenRestrict(MimeDecField *field, const char *search_start, + const char *search_end, uint32_t *tlen, uint32_t max_len, bool *toolong) { uint8_t *fptr, *tptr = NULL, *tok = NULL; + if (toolong) + *toolong = false; + SCLogDebug("Looking for token: %s", search_start); /* Check for token definition */ - fptr = FindBuffer(field->value, field->value_len, (const uint8_t *)search_start, strlen(search_start)); + size_t ss_len = strlen(search_start); + fptr = FindBuffer(field->value, field->value_len, (const uint8_t *)search_start, ss_len); if (fptr != NULL) { - fptr += strlen(search_start); /* Start at end of start string */ - tok = GetToken(fptr, field->value_len - (fptr - field->value), search_end, - &tptr, tlen); - if (tok != NULL) { - SCLogDebug("Found mime token"); + fptr += ss_len; /* Start at end of start string */ + uint32_t offset = fptr - field->value; + if (offset > field->value_len) { + return tok; + } + tok = GetToken(fptr, field->value_len - offset, search_end, &tptr, tlen); + if (tok == NULL) { + return tok; + } + SCLogDebug("Found mime token"); + + /* Compare the actual token length against the maximum */ + if (toolong && max_len && *tlen > max_len) { + SCLogDebug("Token length %d exceeds length restriction %d; truncating", *tlen, max_len); + *toolong = true; + *tlen = max_len; } } return tok; } +/** + * \brief Finds a mime header token within the specified field + * + * \param field The current field + * \param search_start The start of the search (ie. boundary=\") + * \param search_end The end of the search (ie. \") + * \param tlen The output length of the token (if found) + * + * \return A pointer to the token if found, otherwise NULL if not found + */ +static uint8_t * FindMimeHeaderToken(MimeDecField *field, const char *search_start, + const char *search_end, uint32_t *tlen) +{ + return FindMimeHeaderTokenRestrict(field, search_start, search_end, tlen, 0); +} + /** * \brief Processes the current line for mime headers and also does post-processing * when all headers found @@ -1899,7 +1932,7 @@ static int ProcessMimeHeaders(const uint8_t *buf, uint32_t len, /* Check for file attachment in content disposition */ field = MimeDecFindField(entity, CTNT_DISP_STR); if (field != NULL) { - bptr = FindMimeHeaderToken(field, "filename=", TOK_END_STR, &blen); + bptr = FindMimeHeaderTokenRestrict(field, "filename=", TOK_END_STR, &blen, NAME_MAX); if (bptr != NULL) { SCLogDebug("File attachment found in disposition"); entity->ctnt_flags |= CTNT_IS_ATTACHMENT; @@ -1941,7 +1974,7 @@ static int ProcessMimeHeaders(const uint8_t *buf, uint32_t len, /* Look for file name (if not already found) */ if (!(entity->ctnt_flags & CTNT_IS_ATTACHMENT)) { - bptr = FindMimeHeaderToken(field, "name=", TOK_END_STR, &blen); + bptr = FindMimeHeaderTokenRestrict(field, "name=", TOK_END_STR, &blen, NAME_MAX); if (bptr != NULL) { SCLogDebug("File attachment found"); entity->ctnt_flags |= CTNT_IS_ATTACHMENT;