shadow-utils/shadow-4.8.1-getentropy_random_bytes.patch
Björn Esser a6d57fc8a3
Add a patch to obtain random bytes using getentropy()
Signed-off-by: Björn Esser <besser82@fedoraproject.org>
2021-07-04 13:04:39 +02:00

124 lines
3.9 KiB
Diff

From c82ed0c15e0e9e47df0b4c22672b72e35f061a9d
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
Date: Sun, 4 Jul 2021 12:10:11 +0200
Subject: [PATCH] libmisc/salt.c: Use secure system ressources to obtain random
bytes.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In a previous commit we introduced /dev/urandom as a source to obtain
random bytes from. This may not be available on all systems, or when
operating inside of a chroot.
Almost all systems provide functions to obtain random bytes from
secure system ressources. Thus we should prefer to use these, and
fall back to /dev/urandom, if there is no such function present, as
a last resort.
Signed-off-by: Björn Esser <besser82@fedoraproject.org>
---
configure.ac | 17 +++++++++--------
libmisc/salt.c | 42 ++++++++++++++++++++++++++++++++++++------
2 files changed, 45 insertions(+), 14 deletions(-)
Index: shadow-4.8.1/configure.ac
===================================================================
--- shadow-4.8.1.orig/configure.ac
+++ shadow-4.8.1/configure.ac
@@ -44,18 +44,19 @@ AC_HEADER_STDBOOL
AC_CHECK_HEADERS(crypt.h errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \
utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \
- utime.h ulimit.h sys/capability.h sys/resource.h gshadow.h lastlog.h \
- locale.h rpc/key_prot.h netdb.h acl/libacl.h attr/libattr.h \
- attr/error_context.h)
+ utime.h ulimit.h sys/capability.h sys/random.h sys/resource.h \
+ gshadow.h lastlog.h locale.h rpc/key_prot.h netdb.h acl/libacl.h \
+ attr/libattr.h attr/error_context.h)
dnl shadow now uses the libc's shadow implementation
AC_CHECK_HEADER([shadow.h],,[AC_MSG_ERROR([You need a libc with shadow.h])])
-AC_CHECK_FUNCS(l64a fchmod fchown fsync futimes getgroups gethostname getspnam \
- gettimeofday getusershell getutent initgroups lchown lckpwdf lstat \
- lutimes memcpy memset setgroups sigaction strchr updwtmp updwtmpx innetgr \
- getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo \
- ruserok dlopen)
+AC_CHECK_FUNCS(arc4random_buf l64a fchmod fchown fsync futimes getgroups \
+ gethostname getentropy getrandom getspnam gettimeofday getusershell \
+ getutent initgroups lchown lckpwdf lstat lutimes memcpy memset \
+ setgroups sigaction strchr updwtmp updwtmpx innetgr getpwnam_r \
+ getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo ruserok \
+ dlopen)
AC_SYS_LARGEFILE
dnl Checks for typedefs, structures, and compiler characteristics.
Index: shadow-4.8.1/libmisc/salt.c
===================================================================
--- shadow-4.8.1.orig/libmisc/salt.c
+++ shadow-4.8.1/libmisc/salt.c
@@ -15,6 +15,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#if HAVE_SYS_RANDOM_H
+#include <sys/random.h>
+#endif
#include "prototypes.h"
#include "defines.h"
#include "getdef.h"
@@ -128,19 +131,46 @@ static /*@observer@*/char *l64a (long va
static long read_random_bytes (void)
{
long randval = 0;
- FILE *f = fopen ("/dev/urandom", "r");
- if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval))
- {
- fprintf (shadow_logfd,
- _("Unable to read from /dev/urandom.\n"));
+#ifdef HAVE_ARC4RANDOM_BUF
+ /* arc4random_buf, if it exists, can never fail. */
+ arc4random_buf (&randval, sizeof (randval));
+ goto end;
+
+#elif defined(HAVE_GETENTROPY)
+ /* getentropy may exist but lack kernel support. */
+ if (getentropy (&randval, sizeof (randval))) {
+ goto fail;
+ }
+
+ goto end;
+
+#elif defined(HAVE_GETRANDOM)
+ /* Likewise getrandom. */
+ if ((size_t) getrandom (&randval, sizeof (randval), 0) != sizeof (randval)) {
+ goto fail;
+ }
+ goto end;
+
+#else
+ FILE *f = fopen ("/dev/urandom", "r");
+
+ if (fread (&randval, sizeof (randval), 1, f) != sizeof (randval)) {
fclose(f);
- exit (1);
+ goto fail;
}
fclose(f);
+ goto end;
+#endif
+
+fail:
+ fprintf (shadow_logfd,
+ _("Unable to obtain random bytes.\n"));
+ exit (1);
+end:
return randval;
}