From 39ace91b8e930d3167bacf7f5395eb1eb43f371d Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 21 Dec 2021 14:28:51 -0500 Subject: [PATCH] libuuid: try to use getrandom() or getentropy() if available If getrandom() or getentropy() is available, use these interfaces in favor of opening /dev/[u]random. This avoids a potential TSAN problem that could potentially cause a fd leak when trying to open /dev/urandom. (Which is not a disaster, but these interfaces are more foolproof and avoids needing to open a file descriptor in a library, which is a good thing.) Addresses-Google-Bug: #198050608 Signed-off-by: Theodore Ts'o --- configure | 4 ++-- configure.ac | 3 +++ lib/config.h.in | 9 +++++++++ lib/uuid/gen_uuid.c | 16 +++++++++++++++- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 405b730..effd929 100755 --- a/configure +++ b/configure @@ -10458,7 +10458,7 @@ fi done fi -for ac_header in dirent.h errno.h execinfo.h getopt.h malloc.h mntent.h paths.h pthread.h semaphore.h setjmp.h signal.h stdarg.h stdint.h stdlib.h termios.h termio.h unistd.h utime.h attr/xattr.h linux/falloc.h linux/fd.h linux/fsmap.h linux/major.h linux/loop.h linux/types.h net/if_dl.h netinet/in.h sys/acl.h sys/disklabel.h sys/disk.h sys/file.h sys/ioctl.h sys/key.h sys/mkdev.h sys/mman.h sys/mount.h sys/prctl.h sys/resource.h sys/select.h sys/socket.h sys/sockio.h sys/stat.h sys/syscall.h sys/sysmacros.h sys/time.h sys/types.h sys/un.h sys/wait.h sys/xattr.h +for ac_header in dirent.h errno.h execinfo.h getopt.h malloc.h mntent.h paths.h pthread.h semaphore.h setjmp.h signal.h stdarg.h stdint.h stdlib.h termios.h termio.h unistd.h utime.h attr/xattr.h linux/falloc.h linux/fd.h linux/fsmap.h linux/major.h linux/loop.h linux/types.h net/if_dl.h netinet/in.h sys/acl.h sys/disklabel.h sys/disk.h sys/file.h sys/ioctl.h sys/key.h sys/mkdev.h sys/mman.h sys/mount.h sys/prctl.h sys/random.h sys/resource.h sys/select.h sys/socket.h sys/sockio.h sys/stat.h sys/syscall.h sys/sysmacros.h sys/time.h sys/types.h sys/un.h sys/wait.h sys/xattr.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -11254,7 +11254,7 @@ fi if test -n "$DLOPEN_LIB" ; then ac_cv_func_dlopen=yes fi -for ac_func in __secure_getenv add_key backtrace chflags dlopen fadvise64 fallocate fallocate64 fchown fcntl fdatasync fstat64 fsync ftruncate64 futimes getcwd getdtablesize gethostname getmntinfo getpwuid_r getrlimit getrusage jrand48 keyctl llistxattr llseek lseek64 mallinfo mbstowcs memalign mempcpy mmap msync nanosleep open64 pathconf posix_fadvise posix_fadvise64 posix_memalign prctl pread pwrite pread64 pwrite64 secure_getenv setmntent setresgid setresuid snprintf srandom stpcpy strcasecmp strdup strnlen strptime strtoull sync_file_range sysconf usleep utime utimes valloc +for ac_func in __secure_getenv add_key backtrace chflags dlopen fadvise64 fallocate fallocate64 fchown fcntl fdatasync fstat64 fsync ftruncate64 futimes getcwd getdtablesize getentropy gethostname getmntinfo getpwuid_r getrandom getrlimit getrusage jrand48 keyctl llistxattr llseek lseek64 mallinfo mbstowcs memalign mempcpy mmap msync nanosleep open64 pathconf posix_fadvise posix_fadvise64 posix_memalign prctl pread pwrite pread64 pwrite64 secure_getenv setmntent setresgid setresuid snprintf srandom stpcpy strcasecmp strdup strnlen strptime strtoull sync_file_range sysconf usleep utime utimes valloc do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/configure.ac b/configure.ac index 824a93d..dff3d1c 100644 --- a/configure.ac +++ b/configure.ac @@ -1005,6 +1005,7 @@ AC_CHECK_HEADERS(m4_flatten([ sys/mman.h sys/mount.h sys/prctl.h + sys/random.h sys/resource.h sys/select.h sys/socket.h @@ -1200,9 +1201,11 @@ AC_CHECK_FUNCS(m4_flatten([ futimes getcwd getdtablesize + getentropy gethostname getmntinfo getpwuid_r + getrandom getrlimit getrusage jrand48 diff --git a/lib/config.h.in b/lib/config.h.in index 4bc7e8e..9c9de65 100644 --- a/lib/config.h.in +++ b/lib/config.h.in @@ -127,6 +127,9 @@ /* Define to 1 if you have the `getdtablesize' function. */ #undef HAVE_GETDTABLESIZE +/* Define to 1 if you have the `getentropy' function. */ +#undef HAVE_GETENTROPY + /* Define to 1 if you have the `gethostname' function. */ #undef HAVE_GETHOSTNAME @@ -139,6 +142,9 @@ /* Define to 1 if you have the `getpwuid_r' function. */ #undef HAVE_GETPWUID_R +/* Define to 1 if you have the `getrandom' function. */ +#undef HAVE_GETRANDOM + /* Define to 1 if you have the `getrlimit' function. */ #undef HAVE_GETRLIMIT @@ -400,6 +406,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PRCTL_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_RANDOM_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_RESOURCE_H diff --git a/lib/uuid/gen_uuid.c b/lib/uuid/gen_uuid.c index 89179b6..14c98eb 100644 --- a/lib/uuid/gen_uuid.c +++ b/lib/uuid/gen_uuid.c @@ -70,6 +70,9 @@ #ifdef HAVE_SYS_IOCTL_H #include #endif +#ifdef HAVE_SYS_RANDOM_H +#include +#endif #ifdef HAVE_SYS_SOCKET_H #include #endif @@ -174,10 +177,21 @@ static int get_random_fd(void) */ static void get_random_bytes(void *buf, int nbytes) { - int i, n = nbytes, fd = get_random_fd(); + int i, n = nbytes, fd; int lose_counter = 0; unsigned char *cp = buf; +#ifdef HAVE_GETRANDOM + i = getrandom(buf, nbytes, 0); + if (i == nbytes) + return; +#endif +#ifdef HAVE_GETENTROPY + if (getentropy(buf, nbytes) == 0) + return; +#endif + + fd = get_random_fd(); if (fd >= 0) { while (n > 0) { i = read(fd, cp, n); -- 1.8.3.1