Avoid compiling some code paths that are unreachable when fuzzing.

This commit is contained in:
Todd C. Miller
2022-12-29 10:40:48 -07:00
parent 8a5e9ffb43
commit 2e9e1c80f5
3 changed files with 80 additions and 62 deletions

View File

@@ -239,8 +239,10 @@ warning(const char *errstr, const char *fmt, va_list ap)
fputs(": ", stderr); fputs(": ", stderr);
fputs(errstr, stderr); fputs(errstr, stderr);
} }
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if (sudo_term_is_raw(fileno(stderr))) if (sudo_term_is_raw(fileno(stderr)))
putc('\r', stderr); putc('\r', stderr);
#endif
putc('\n', stderr); putc('\n', stderr);
} }

View File

@@ -80,6 +80,13 @@
#include "sudo_digest.h" #include "sudo_digest.h"
#include "sudo_rand.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) #if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
# define MAP_ANON MAP_ANONYMOUS # define MAP_ANON MAP_ANONYMOUS
#endif #endif
@@ -106,6 +113,7 @@
int sudo_getentropy(void *buf, size_t len); int sudo_getentropy(void *buf, size_t len);
static int getentropy_getrandom(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_sysctl(void *buf, size_t len);
static int getentropy_urandom(void *buf, size_t len, const char *path, static int getentropy_urandom(void *buf, size_t len, const char *path,
int devfscheck); int devfscheck);
@@ -114,22 +122,7 @@ static int gotdata(char *buf, size_t len);
#ifdef HAVE_DL_ITERATE_PHDR #ifdef HAVE_DL_ITERATE_PHDR
static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data); static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
#endif #endif
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
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
}
int int
sudo_getentropy(void *buf, size_t len) sudo_getentropy(void *buf, size_t len)
@@ -145,7 +138,9 @@ sudo_getentropy(void *buf, size_t len)
if (ret != -1) if (ret != -1)
return (ret); return (ret);
#ifdef HAVE_OPENSSL #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
#if defined(HAVE_OPENSSL)
if (RAND_bytes(buf, len) == 1) if (RAND_bytes(buf, len) == 1)
return (0); return (0);
#endif #endif
@@ -193,14 +188,44 @@ sudo_getentropy(void *buf, size_t len)
return (ret); return (ret);
errno = EIO; errno = EIO;
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
return (ret); return (ret);
} }
/* #if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
* This is an open source non-commercial project. Dear PVS-Studio, please check it. static int
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com 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. * Basic validity checking; wish we could do better.
*/ */
@@ -338,39 +363,6 @@ getentropy_sysctl(void *buf, size_t len)
} }
#endif #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 #ifdef HAVE_CLOCK_GETTIME
static const int cl[] = { static const int cl[] = {
CLOCK_REALTIME, CLOCK_REALTIME,
@@ -409,6 +401,22 @@ getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data)
} }
#endif #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 static int
getentropy_fallback(void *buf, size_t len) getentropy_fallback(void *buf, size_t len)
{ {
@@ -638,5 +646,6 @@ done:
freezero(results, digest_len); freezero(results, digest_len);
return (ret); return (ret);
} }
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
#endif /* HAVE_GETENTROPY */ #endif /* HAVE_GETENTROPY */

View File

@@ -631,7 +631,6 @@ sudo_conf_init(int conf_types)
int int
sudo_conf_read_v1(const char *conf_file, int conf_types) sudo_conf_read_v1(const char *conf_file, int conf_types)
{ {
struct stat sb;
FILE *fp = NULL; FILE *fp = NULL;
int fd, ret = false; int fd, ret = false;
char *prev_locale, *line = NULL; 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') if (prev_locale[0] != 'C' || prev_locale[1] != '\0')
setlocale(LC_ALL, "C"); setlocale(LC_ALL, "C");
if (conf_file != NULL) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
fd = open(conf_file, O_RDONLY); if (conf_file == NULL) {
if (fd == -1) { struct stat sb;
sudo_warn(U_("unable to open %s"), conf_file);
goto done;
}
} else {
int error; int error;
conf_file = _PATH_SUDO_CONF; conf_file = _PATH_SUDO_CONF;
fd = sudo_secure_open_file(conf_file, ROOT_UID, -1, &sb, &error); fd = sudo_secure_open_file(conf_file, ROOT_UID, -1, &sb, &error);
if (fd == -1) { if (fd == -1) {
@@ -689,6 +685,17 @@ sudo_conf_read_v1(const char *conf_file, int conf_types)
} }
goto done; 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) { if ((fp = fdopen(fd, "r")) == NULL) {