From 9db90b0f8cdf41d5f8241babe50bed1578e8cfa1 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Mon, 14 Aug 2023 05:20:03 -0700 Subject: til_str: handle overflows in til_str_appendf() In the wholesale transition to til_module_setup_full() there's been a lot more problematic randomized setups either extremely deep or plain infinite. Due to the primitive escaping mechanism performed by til_settings_as_arg(), where escape patterns grow exponentially with depth, it's quite realistic (and observed) for these problematic setups to exceed SIZE_MAX. So I'm putting some guard rails in to cap a given til_str_t to SIZE_MAX. It might make more sense to move the limit well below SIZE_MAX, but this should at least prevent overflows. --- src/til_str.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/til_str.c b/src/til_str.c index 4c8a0ad..0a4a640 100644 --- a/src/til_str.c +++ b/src/til_str.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -25,6 +26,7 @@ struct til_str_t { #define TIL_STR_MIN_SIZE 64 +#define TIL_STR_MAX_GROWBY (TIL_STR_MIN_SIZE * 1024) /* alloc always returns a buf w/nul terminator present */ @@ -118,11 +120,18 @@ int til_str_appendf(til_str_t *str, const char *format, ...) len = vsnprintf(NULL, 0, format, ap); va_end(ap); + if (SIZE_MAX - len < str->size.used) + return -EOVERFLOW; + if (str->size.used + len > str->size.allocated) { char *new; - str->size.growby += TIL_STR_MIN_SIZE; + if (str->size.growby < TIL_STR_MAX_GROWBY) + str->size.growby += TIL_STR_MIN_SIZE; + len = MAX(str->size.growby, len); + if (SIZE_MAX - len < str->size.used) + len = SIZE_MAX - str->size.used; new = realloc(str->buf, str->size.used + len); if (!new) -- cgit v1.2.1