1
0
xorg-x11-server/u_Use-better-fallbacks-to-generate-cookies-if-arc4rand.patch
Stefan Dirsch 6ff43929b0 Accepting request 1189636 from home:jamborm:gcc14test-m
- Added xorg-xserver-e89edec497ba.patch to fix incompatible pointer
  type error with GCC 14.

If the request is OK, please forward it to Factory soon too so that we
can switch the default compiler.  Thanks!

OBS-URL: https://build.opensuse.org/request/show/1189636
OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xorg-x11-server?expand=0&rev=891
2024-08-01 10:31:47 +00:00

225 lines
6.1 KiB
Diff

From 44a643812ce3c07cd38972abfa9dbd163529c192 Mon Sep 17 00:00:00 2001
From: Matthias Gerstner <mgerstner@suse.de>
Date: Thu, 13 Jul 2017 14:58:04 +0200
Subject: [PATCH] Use better fallbacks to generate cookies if arc4random_buf(3)
is unavailable
References: bsc#1025084
If arc4random_buf() is not available for generating cookies:
- use getentropy(), if available (which was only recently added to
glibc)
- use getrandom() via syscall(), if available (there was no glibc
wrapper for this syscall for a long time)
- if all else fails, directly read from /dev/urandom as before, but
employ O_CLOEXEC, do an OsAbort() in case the random data couldn't be
read to avoid unsecure situations. Don't know if that's too hard a
measure but it shouldn't actually occur except on maximum number of
FDs reached
Reviewed-by: Stefan Dirsch <sndirsch@suse.de>
---
configure.ac | 4 +-
include/dix-config.h.in | 6 +++
os/auth.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 141 insertions(+), 7 deletions(-)
Index: xorg-server-21.1.9/configure.ac
===================================================================
--- xorg-server-21.1.9.orig/configure.ac
+++ xorg-server-21.1.9/configure.ac
@@ -132,7 +132,7 @@ AM_CONDITIONAL(SPECIAL_DTRACE_OBJECTS, [
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h dlfcn.h stropts.h \
- fnmatch.h sys/mkdev.h sys/sysmacros.h sys/utsname.h])
+ fnmatch.h sys/mkdev.h sys/sysmacros.h sys/utsname.h sys/syscall.h])
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
Index: xorg-server-21.1.9/include/dix-config.h.in
===================================================================
--- xorg-server-21.1.9.orig/include/dix-config.h.in
+++ xorg-server-21.1.9/include/dix-config.h.in
@@ -149,6 +149,9 @@
/* Define to 1 if you have the `arc4random_buf' function. */
#undef HAVE_ARC4RANDOM_BUF
+/* Define to 1 if you have the `getentropy' function. */
+#undef HAVE_GETENTROPY
+
/* Define to use libc SHA1 functions */
#undef HAVE_SHA1_IN_LIBC
@@ -226,6 +229,9 @@
/* Define to 1 if you have the <sys/utsname.h> header file. */
#undef HAVE_SYS_UTSNAME_H
+/* Define to 1 if you have the <sys/syscall.h> header file. */
+#undef HAVE_SYS_SYSCALL_H
+
/* Define to 1 if you have the `timingsafe_memcmp' function. */
#undef HAVE_TIMINGSAFE_MEMCMP
Index: xorg-server-21.1.9/os/auth.c
===================================================================
--- xorg-server-21.1.9.orig/os/auth.c
+++ xorg-server-21.1.9/os/auth.c
@@ -34,6 +34,10 @@ from The Open Group.
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
+#include <errno.h>
+#ifdef HAVE_SYS_SYSCALL_H
+#include <syscall.h>
+#endif
#include <X11/X.h>
#include <X11/Xauth.h>
@@ -308,16 +312,140 @@ GenerateAuthorization(unsigned name_leng
#endif /* XCSECURITY */
+#if ! defined(HAVE_ARC4RANDOM_BUF)
+
+// fallback function to get random data directly from /dev/urandom
+
+static int
+GetUrandom ( char *buffer, size_t length )
+{
+ int random_fd = -1;
+ int res = -1;
+ size_t filled = 0;
+
+ // larger requests are typically rejected by getentropy() / getrandom()
+ // because they could block or return partially filled buffers
+ if( length > 256 ) {
+ errno = EIO;
+ return -1;
+ }
+
+ random_fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
+
+ if( random_fd == -1 ) {
+ return -1;
+ }
+
+ while( filled < length ) {
+ res = read(random_fd, (char*)buffer + filled, length - filled);
+
+ if( res == -1 ) {
+ // shouldn't actually happen acc. to man(4) random,
+ // but you never know
+ if( errno == EINTR ) {
+ continue;
+ }
+
+ res = errno;
+ close(random_fd);
+ errno = res;
+ return -1;
+ }
+ else if( res == 0 ) {
+ close(random_fd);
+ // no more bytes available? should not happen
+ errno = EIO;
+ return -1;
+ }
+
+ filled += res;
+ }
+
+ close(random_fd);
+
+ return 0;
+}
+
+#endif // ! defined(HAVE_ARC4RANDOM_BUF)
+
+#if !defined(HAVE_GETENTROPY) && defined(HAVE_SYS_SYSCALL_H) && defined(SYS_getrandom)
+# define TRY_GETRANDOM
+#endif
+
+#ifdef TRY_GETRANDOM
+
+/*
+ * wrapper for the getrandom() syscall which was for a long time implemented
+ * in the Linux kernel, but not wrapped in glibc
+ */
+static int
+GetRandom ( char *buffer, size_t length )
+{
+ int res;
+ size_t filled = 0;
+
+ // larger requests are typically rejected by getentropy() / getrandom()
+ // because they could block or return partially filled buffers
+ if( length > 256 )
+ {
+ errno = EIO;
+ return -1;
+ }
+
+ while( filled < length )
+ {
+ /*
+ * glibc does not contain a syscall wrapper for this in older
+ * versions
+ */
+ res = syscall(SYS_getrandom, (char*)buffer + filled, length - filled, 0);
+
+ if( res == -1 )
+ {
+ if( errno == EINTR ) {
+ continue;
+ }
+
+ return -1;
+ }
+ else if( res == 0 )
+ {
+ // no more bytes available? should not happen
+ errno = EIO;
+ return -1;
+ }
+
+ filled += res;
+ }
+
+ return 0;
+}
+
+#endif /* TRY_GETRANDOM */
+
void
GenerateRandomData(int len, char *buf)
{
#ifdef HAVE_ARC4RANDOM_BUF
arc4random_buf(buf, len);
#else
- int fd;
+ int ret = -1;
+# ifdef HAVE_GETENTROPY
+ /* use getentropy instead */
+ ret = getentropy (buf, len);
+# elif defined(TRY_GETRANDOM)
+ /* try getrandom() wrapper */
+ ret = GetRandom(buf, len);
+# endif
+
+ if( ret == -1 ) {
+ // fallback to manual reading of /dev/urandom
+ ret = GetUrandom(buf, len);
+ }
- fd = open("/dev/urandom", O_RDONLY);
- read(fd, buf, len);
- close(fd);
-#endif
+ if( ret == -1 ) {
+ // no error return possible, rather abort than have security problems
+ OsAbort();
+ }
+#endif // HAVE_ARC4RANDOM_BUF
}