From 732110428e1da523747c7f90da89a7462f95d4bf Mon Sep 17 00:00:00 2001 From: Rose <83477269+AtariDreams@users.noreply.github.com> Date: Mon, 3 Jul 2023 22:03:39 -0400 Subject: [PATCH] Fix fuzzing errors We should be checking for integer overflow, rather than checking if size is 0. Additionally, we should set errno to ENOMEM when this overflow happens. Finally, the most efficient implementation of the round-up-to-2 algorithm involves the clz intrinsic. --- lib/util/parseln.c | 18 +++++++++++++++--- lib/util/roundup.c | 12 ++++-------- logsrvd/logsrvd_journal.c | 2 ++ 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/lib/util/parseln.c b/lib/util/parseln.c index 5dae211d5..892894a3f 100644 --- a/lib/util/parseln.c +++ b/lib/util/parseln.c @@ -23,10 +23,11 @@ #include +#include +#include #include #include #include -#include #ifdef HAVE_STDBOOL_H # include #else @@ -91,9 +92,20 @@ sudo_parseln_v2(char **bufp, size_t *bufsizep, unsigned int *lineno, FILE *fp, i if (*bufp == NULL || total + len >= *bufsizep) { void *newbuf; - const size_t newsize = sudo_pow2_roundup(total + len + 1); + const size_t size = total + len + 1; + const size_t newsize = sudo_pow2_roundup(size); - if (newsize == 0 || (newbuf = realloc(*bufp, newsize)) == NULL) { + if (newsize < size) { + /* overflow */ + errno = ENOMEM; + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, + "unable to allocate memory"); + len = -1; + total = 0; + break; + } + + if ((newbuf = realloc(*bufp, newsize)) == NULL) { sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "unable to allocate memory"); len = -1; diff --git a/lib/util/roundup.c b/lib/util/roundup.c index 7caf8b454..2dd1957d6 100644 --- a/lib/util/roundup.c +++ b/lib/util/roundup.c @@ -47,14 +47,10 @@ sudo_pow2_roundup_v2(size_t len) { if (len < 64) return 64; - len--; - len |= len >> 1; - len |= len >> 2; - len |= len >> 4; - len |= len >> 8; - len |= len >> 16; + #ifdef __LP64__ - len |= len >> 32; + return 1 << (64 - __builtin_clzl(len - 1)); +#else + return 1 << (32 - __builtin_clz(len - 1)); #endif - return ++len; } diff --git a/logsrvd/logsrvd_journal.c b/logsrvd/logsrvd_journal.c index 0983d1f67..d28ad9ad5 100644 --- a/logsrvd/logsrvd_journal.c +++ b/logsrvd/logsrvd_journal.c @@ -270,11 +270,13 @@ journal_seek(struct timespec *target, struct connection_closure *closure) bufsize = sudo_pow2_roundup(msg_len); if (bufsize < msg_len) { /* overflow */ + errno = ENOMEM; closure->errstr = _("unable to allocate memory"); break; } free(buf); if ((buf = malloc(bufsize)) == NULL) { + errno = ENOMEM; closure->errstr = _("unable to allocate memory"); break; }