diff options
author | Todd C. Miller <Todd.Miller@sudo.ws> | 2023-03-01 13:58:32 -0700 |
---|---|---|
committer | Todd C. Miller <Todd.Miller@sudo.ws> | 2023-03-01 13:58:32 -0700 |
commit | 0ef3520a3cef658dc208510d7256f9f36bad1d88 (patch) | |
tree | 39d2e5fc69733a2acdceded4b8845d6db62aa73f /logsrvd/logsrvd.c | |
parent | f630581f5f28b964e9dcf43b4451572cde0baf51 (diff) | |
download | sudo-0ef3520a3cef658dc208510d7256f9f36bad1d88.tar.gz |
Check for sudo_pow2_roundup() overflow.
Calling sudo_pow2_roundup(INT_MAX+2) will return since there is no
power of 2 larger than INT_MAX+1 that fits in an unsigned int.
This is not an issue in practice since we restrict messages to 2Mib.
Diffstat (limited to 'logsrvd/logsrvd.c')
-rw-r--r-- | logsrvd/logsrvd.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/logsrvd/logsrvd.c b/logsrvd/logsrvd.c index 17edb84a5..891ce8115 100644 --- a/logsrvd/logsrvd.c +++ b/logsrvd/logsrvd.c @@ -297,23 +297,31 @@ get_free_buf(size_t len, struct connection_closure *closure) if (buf != NULL) { TAILQ_REMOVE(&closure->free_bufs, buf, entries); } else { - if ((buf = calloc(1, sizeof(*buf))) == NULL) { - sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - debug_return_ptr(NULL); - } + if ((buf = calloc(1, sizeof(*buf))) == NULL) + goto oom; } if (len > buf->size) { - free(buf->data); - buf->size = sudo_pow2_roundup(len); - if ((buf->data = malloc(buf->size)) == NULL) { - sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - free(buf); - buf = NULL; + const unsigned int new_size = sudo_pow2_roundup(len); + if (new_size < len) { + /* overflow */ + errno = ENOMEM; + goto oom; } + free(buf->data); + if ((buf->data = malloc(new_size)) == NULL) + goto oom; + buf->size = new_size; } debug_return_ptr(buf); +oom: + if (buf != NULL) { + free(buf->data); + free(buf); + } + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + debug_return_ptr(NULL); } static bool |