summaryrefslogtreecommitdiff
path: root/logsrvd
diff options
context:
space:
mode:
authorTodd C. Miller <Todd.Miller@sudo.ws>2023-03-01 13:58:32 -0700
committerTodd C. Miller <Todd.Miller@sudo.ws>2023-03-01 13:58:32 -0700
commit0ef3520a3cef658dc208510d7256f9f36bad1d88 (patch)
tree39d2e5fc69733a2acdceded4b8845d6db62aa73f /logsrvd
parentf630581f5f28b964e9dcf43b4451572cde0baf51 (diff)
downloadsudo-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')
-rw-r--r--logsrvd/logsrv_util.c18
-rw-r--r--logsrvd/logsrvd.c28
-rw-r--r--logsrvd/logsrvd_journal.c5
-rw-r--r--logsrvd/sendlog.c15
4 files changed, 47 insertions, 19 deletions
diff --git a/logsrvd/logsrv_util.c b/logsrvd/logsrv_util.c
index f70604d52..118b81bb4 100644
--- a/logsrvd/logsrv_util.c
+++ b/logsrvd/logsrv_util.c
@@ -62,18 +62,21 @@ expand_buf(struct connection_buffer *buf, unsigned int needed)
if (buf->size < needed) {
/* Expand buffer. */
- needed = sudo_pow2_roundup(needed);
+ const unsigned int newsize = sudo_pow2_roundup(needed);
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
- "expanding buffer from %u to %u", buf->size, needed);
- if ((newdata = malloc(needed)) == NULL) {
- sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
- debug_return_bool(false);
+ "expanding buffer from %u to %u", buf->size, newsize);
+ if (newsize < needed) {
+ /* overflow */
+ errno = ENOMEM;
+ goto oom;
}
+ if ((newdata = malloc(newsize)) == NULL)
+ goto oom;
if (buf->len != buf->off)
memcpy(newdata, buf->data + buf->off, buf->len - buf->off);
free(buf->data);
buf->data = newdata;
- buf->size = needed;
+ buf->size = newsize;
} else {
/* Just reset existing buffer. */
if (buf->len != buf->off) {
@@ -85,6 +88,9 @@ expand_buf(struct connection_buffer *buf, unsigned int needed)
buf->off = 0;
debug_return_bool(true);
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ debug_return_bool(false);
}
/*
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
diff --git a/logsrvd/logsrvd_journal.c b/logsrvd/logsrvd_journal.c
index 354d71c80..0983d1f67 100644
--- a/logsrvd/logsrvd_journal.c
+++ b/logsrvd/logsrvd_journal.c
@@ -268,6 +268,11 @@ journal_seek(struct timespec *target, struct connection_closure *closure)
if (msg_len > bufsize) {
bufsize = sudo_pow2_roundup(msg_len);
+ if (bufsize < msg_len) {
+ /* overflow */
+ closure->errstr = _("unable to allocate memory");
+ break;
+ }
free(buf);
if ((buf = malloc(bufsize)) == NULL) {
closure->errstr = _("unable to allocate memory");
diff --git a/logsrvd/sendlog.c b/logsrvd/sendlog.c
index 98d5ecc10..ebf6c9d7b 100644
--- a/logsrvd/sendlog.c
+++ b/logsrvd/sendlog.c
@@ -256,7 +256,7 @@ get_free_buf(size_t len, struct client_closure *closure)
if (len > buf->size) {
free(buf->data);
buf->size = sudo_pow2_roundup(len);
- if ((buf->data = malloc(buf->size)) == NULL) {
+ if (buf->size < len || (buf->data = malloc(buf->size)) == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
free(buf);
buf = NULL;
@@ -285,13 +285,22 @@ read_io_buf(struct client_closure *closure)
/* Expand buf as needed. */
if (timing->u.nbytes > closure->bufsize) {
+ const size_t new_size = sudo_pow2_roundup(timing->u.nbytes);
+ if (new_size < timing->u.nbytes) {
+ /* overflow */
+ errno = ENOMEM;
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ timing->u.nbytes = 0;
+ debug_return_bool(false);
+ }
free(closure->buf);
- closure->bufsize = sudo_pow2_roundup(timing->u.nbytes);
- if ((closure->buf = malloc(closure->bufsize)) == NULL) {
+ if ((closure->buf = malloc(new_size)) == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ closure->bufsize = 0;
timing->u.nbytes = 0;
debug_return_bool(false);
}
+ closure->bufsize = new_size;
}
nread = iolog_read(&closure->iolog_files[timing->event], closure->buf,