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; }