diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2023-08-14 05:20:03 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2023-08-14 05:20:03 -0700 |
commit | 9db90b0f8cdf41d5f8241babe50bed1578e8cfa1 (patch) | |
tree | b348d4cecb30456cabcee895960551ea78cd3ca0 | |
parent | 210580bb0bbd14c02c2ba929012399ec32885de1 (diff) |
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.
-rw-r--r-- | src/til_str.c | 11 |
1 files changed, 10 insertions, 1 deletions
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 <assert.h> #include <stdarg.h> +#include <stdint.h> #include <stdlib.h> #include <string.h> @@ -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) |