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 32d0bd2bbb)
pull/12781/head
Philippe Antoine 11 months ago committed by Victor Julien
parent 0b39cf06f8
commit bab716776b

@ -15,6 +15,7 @@ Syntax::
base64_decode:bytes <value>, offset <value>, 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.

@ -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;

@ -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;

Loading…
Cancel
Save