From: Philippe Antoine Date: Tue, 17 Dec 2024 14:06:25 +0000 (+0100) Subject: detect: limit base64_decode `bytes` to 64KiB X-Git-Tag: suricata-7.0.9~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bab716776ba3561cfbfd1a57fc18ff1f6859f019;p=thirdparty%2Fsuricata.git detect: limit base64_decode `bytes` to 64KiB Ticket: 7613 Avoids potential large per-thread memory allocation. A buffer with the size of the largest decode_base64 buffer size setting would be allocated per thread. As this was a u32, it could mean a per-thread 4GiB memory allocation. 64KiB was already the built-in default for cases where bytes size wasn't specified. (cherry picked from commit 32d0bd2bbb4d486623dec85a94952fde2515f2f0) --- diff --git a/doc/userguide/rules/base64-keywords.rst b/doc/userguide/rules/base64-keywords.rst index 190fdb5bf1..256f6c0133 100644 --- a/doc/userguide/rules/base64-keywords.rst +++ b/doc/userguide/rules/base64-keywords.rst @@ -15,6 +15,7 @@ Syntax:: base64_decode:bytes , offset , relative; The ``bytes`` option specifies how many bytes Suricata should decode and make available for base64_data. +This number is limited to 64KiB. The decoding will stop at the end of the buffer. The ``offset`` option specifies how many bytes Suricata should skip before decoding. diff --git a/src/detect-base64-decode.c b/src/detect-base64-decode.c index 25fdf10e70..5ae38c5721 100644 --- a/src/detect-base64-decode.c +++ b/src/detect-base64-decode.c @@ -28,7 +28,7 @@ #define BASE64_DECODE_MAX 65535 typedef struct DetectBase64Decode_ { - uint32_t bytes; + uint16_t bytes; uint32_t offset; uint8_t relative; } DetectBase64Decode; @@ -111,8 +111,8 @@ int DetectBase64DecodeDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s return det_ctx->base64_decoded_len > 0; } -static int DetectBase64DecodeParse(const char *str, uint32_t *bytes, - uint32_t *offset, uint8_t *relative) +static int DetectBase64DecodeParse( + const char *str, uint16_t *bytes, uint32_t *offset, uint8_t *relative) { const char *bytes_str = NULL; const char *offset_str = NULL; @@ -132,7 +132,7 @@ static int DetectBase64DecodeParse(const char *str, uint32_t *bytes, if (pcre_rc >= 3) { if (pcre2_substring_get_bynumber(match, 2, (PCRE2_UCHAR8 **)&bytes_str, &pcre2_len) == 0) { - if (StringParseUint32(bytes, 10, 0, bytes_str) <= 0) { + if (StringParseUint16(bytes, 10, 0, bytes_str) <= 0) { SCLogError("Bad value for bytes: \"%s\"", bytes_str); goto error; } @@ -186,7 +186,7 @@ error: static int DetectBase64DecodeSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str) { - uint32_t bytes = 0; + uint16_t bytes = 0; uint32_t offset = 0; uint8_t relative = 0; DetectBase64Decode *data = NULL; @@ -238,9 +238,6 @@ static int DetectBase64DecodeSetup(DetectEngineCtx *de_ctx, Signature *s, data->bytes = BASE64_DECODE_MAX; } if (data->bytes > de_ctx->base64_decode_max_len) { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - data->bytes = BASE64_DECODE_MAX; -#endif de_ctx->base64_decode_max_len = data->bytes; } @@ -272,7 +269,7 @@ static int g_http_header_buffer_id = 0; static int DetectBase64TestDecodeParse(void) { int retval = 0; - uint32_t bytes = 0; + uint16_t bytes = 0; uint32_t offset = 0; uint8_t relative = 0; diff --git a/src/detect.h b/src/detect.h index 2379d32538..73fa010d1f 100644 --- a/src/detect.h +++ b/src/detect.h @@ -927,7 +927,7 @@ typedef struct DetectEngineCtx_ { struct SigGroupHead_ *decoder_event_sgh; /* Maximum size of the buffer for decoded base64 data. */ - uint32_t base64_decode_max_len; + uint16_t base64_decode_max_len; /** Store rule file and line so that parsers can use them in errors. */ int rule_line;