diff --git a/lib/util/fatal.c b/lib/util/fatal.c index cf2303ffc..7d2e09d18 100644 --- a/lib/util/fatal.c +++ b/lib/util/fatal.c @@ -239,8 +239,10 @@ warning(const char *errstr, const char *fmt, va_list ap) fputs(": ", stderr); fputs(errstr, stderr); } +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (sudo_term_is_raw(fileno(stderr))) putc('\r', stderr); +#endif putc('\n', stderr); } diff --git a/lib/util/getentropy.c b/lib/util/getentropy.c index dc5c91c02..03526fad2 100644 --- a/lib/util/getentropy.c +++ b/lib/util/getentropy.c @@ -80,6 +80,13 @@ #include "sudo_digest.h" #include "sudo_rand.h" +/* Only use getrandom(2) when fuzzing. */ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +# if !defined(SYS_getrandom) || !defined(GRND_NONBLOCK) +# undef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +# endif +#endif + #if !defined(MAP_ANON) && defined(MAP_ANONYMOUS) # define MAP_ANON MAP_ANONYMOUS #endif @@ -106,6 +113,7 @@ int sudo_getentropy(void *buf, size_t len); static int getentropy_getrandom(void *buf, size_t len); +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION static int getentropy_sysctl(void *buf, size_t len); static int getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck); @@ -114,22 +122,7 @@ static int gotdata(char *buf, size_t len); #ifdef HAVE_DL_ITERATE_PHDR static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data); #endif - -static void * -mmap_anon(void *addr, size_t len, int prot, int flags, off_t offset) -{ -#ifdef MAP_ANON - return mmap(addr, len, prot, flags | MAP_ANON, -1, offset); -#else - int fd; - - if ((fd = open("/dev/zero", O_RDWR)) == -1) - return MAP_FAILED; - addr = mmap(addr, len, prot, flags, fd, offset); - close(fd); - return addr; -#endif -} +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ int sudo_getentropy(void *buf, size_t len) @@ -145,7 +138,9 @@ sudo_getentropy(void *buf, size_t len) if (ret != -1) return (ret); -#ifdef HAVE_OPENSSL +#if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) + +#if defined(HAVE_OPENSSL) if (RAND_bytes(buf, len) == 1) return (0); #endif @@ -193,14 +188,44 @@ sudo_getentropy(void *buf, size_t len) return (ret); errno = EIO; +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ return (ret); } -/* - * This is an open source non-commercial project. Dear PVS-Studio, please check it. - * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com - */ +#if defined(SYS_getrandom) && defined(GRND_NONBLOCK) +static int +getentropy_getrandom(void *buf, size_t len) +{ + int pre_errno = errno; + int ret; + /* + * Try descriptor-less getrandom(), in non-blocking mode. + * + * The design of Linux getrandom is broken. It has an + * uninitialized phase coupled with blocking behaviour, which + * is unacceptable from within a library at boot time without + * possible recovery. See http://bugs.python.org/issue26839#msg267745 + */ + do { + ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK); + } while (ret == -1 && errno == EINTR); + + if (ret < 0 || (size_t)ret != len) + return (-1); + errno = pre_errno; + return (0); +} +#else +static int +getentropy_getrandom(void *buf, size_t len) +{ + errno = ENOTSUP; + return (-1); +} +#endif + +#if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) /* * Basic validity checking; wish we could do better. */ @@ -338,39 +363,6 @@ getentropy_sysctl(void *buf, size_t len) } #endif -#if defined(SYS_getrandom) && defined(GRND_NONBLOCK) -static int -getentropy_getrandom(void *buf, size_t len) -{ - int pre_errno = errno; - int ret; - - /* - * Try descriptor-less getrandom(), in non-blocking mode. - * - * The design of Linux getrandom is broken. It has an - * uninitialized phase coupled with blocking behaviour, which - * is unacceptable from within a library at boot time without - * possible recovery. See http://bugs.python.org/issue26839#msg267745 - */ - do { - ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK); - } while (ret == -1 && errno == EINTR); - - if (ret < 0 || (size_t)ret != len) - return (-1); - errno = pre_errno; - return (0); -} -#else -static int -getentropy_getrandom(void *buf, size_t len) -{ - errno = ENOTSUP; - return (-1); -} -#endif - #ifdef HAVE_CLOCK_GETTIME static const int cl[] = { CLOCK_REALTIME, @@ -409,6 +401,22 @@ getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data) } #endif +static void * +mmap_anon(void *addr, size_t len, int prot, int flags, off_t offset) +{ +#ifdef MAP_ANON + return mmap(addr, len, prot, flags | MAP_ANON, -1, offset); +#else + int fd; + + if ((fd = open("/dev/zero", O_RDWR)) == -1) + return MAP_FAILED; + addr = mmap(addr, len, prot, flags, fd, offset); + close(fd); + return addr; +#endif +} + static int getentropy_fallback(void *buf, size_t len) { @@ -638,5 +646,6 @@ done: freezero(results, digest_len); return (ret); } +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ #endif /* HAVE_GETENTROPY */ diff --git a/lib/util/sudo_conf.c b/lib/util/sudo_conf.c index f2cdee6f6..eab9f4518 100644 --- a/lib/util/sudo_conf.c +++ b/lib/util/sudo_conf.c @@ -631,7 +631,6 @@ sudo_conf_init(int conf_types) int sudo_conf_read_v1(const char *conf_file, int conf_types) { - struct stat sb; FILE *fp = NULL; int fd, ret = false; char *prev_locale, *line = NULL; @@ -652,14 +651,11 @@ sudo_conf_read_v1(const char *conf_file, int conf_types) if (prev_locale[0] != 'C' || prev_locale[1] != '\0') setlocale(LC_ALL, "C"); - if (conf_file != NULL) { - fd = open(conf_file, O_RDONLY); - if (fd == -1) { - sudo_warn(U_("unable to open %s"), conf_file); - goto done; - } - } else { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if (conf_file == NULL) { + struct stat sb; int error; + conf_file = _PATH_SUDO_CONF; fd = sudo_secure_open_file(conf_file, ROOT_UID, -1, &sb, &error); if (fd == -1) { @@ -689,6 +685,17 @@ sudo_conf_read_v1(const char *conf_file, int conf_types) } goto done; } + } else +#else + if (conf_file == NULL) + conf_file = _PATH_SUDO_CONF; +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ + { + fd = open(conf_file, O_RDONLY); + if (fd == -1) { + sudo_warn(U_("unable to open %s"), conf_file); + goto done; + } } if ((fp = fdopen(fd, "r")) == NULL) {