Whamcloud - gitweb
libuuid: try to use getrandom() or getentropy() if available
authorTheodore Ts'o <tytso@mit.edu>
Tue, 21 Dec 2021 19:28:51 +0000 (14:28 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 21 Dec 2021 19:28:51 +0000 (14:28 -0500)
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 <tytso@mit.edu>
configure
configure.ac
lib/config.h.in
lib/uuid/gen_uuid.c

index 405b730..effd929 100755 (executable)
--- 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"
index 824a93d..dff3d1c 100644 (file)
@@ -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
index 4bc7e8e..9c9de65 100644 (file)
 /* 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
 
 /* 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
 
 /* Define to 1 if you have the <sys/prctl.h> header file. */
 #undef HAVE_SYS_PRCTL_H
 
+/* Define to 1 if you have the <sys/random.h> header file. */
+#undef HAVE_SYS_RANDOM_H
+
 /* Define to 1 if you have the <sys/resource.h> header file. */
 #undef HAVE_SYS_RESOURCE_H
 
index 89179b6..14c98eb 100644 (file)
@@ -70,6 +70,9 @@
 #ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #endif
+#ifdef HAVE_SYS_RANDOM_H
+#include <sys/random.h>
+#endif
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
 #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);