diff --git a/u_Use-better-fallbacks-to-generate-cookies-if-arc4rand.patch b/u_Use-better-fallbacks-to-generate-cookies-if-arc4rand.patch new file mode 100644 index 0000000..f2af7b9 --- /dev/null +++ b/u_Use-better-fallbacks-to-generate-cookies-if-arc4rand.patch @@ -0,0 +1,235 @@ +From 44a643812ce3c07cd38972abfa9dbd163529c192 Mon Sep 17 00:00:00 2001 +From: Matthias Gerstner +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 +--- + configure.ac | 4 +- + include/dix-config.h.in | 6 +++ + os/auth.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++-- + 3 files changed, 141 insertions(+), 7 deletions(-) + +Index: xorg-server-1.19.3/configure.ac +=================================================================== +--- xorg-server-1.19.3.orig/configure.ac ++++ xorg-server-1.19.3/configure.ac +@@ -134,7 +134,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/utsname.h]) ++ fnmatch.h sys/mkdev.h sys/utsname.h sys/syscall.h]) + + dnl Checks for typedefs, structures, and compiler characteristics. + AC_C_CONST +@@ -226,7 +226,7 @@ AC_REPLACE_FUNCS([reallocarray strcasecm + AM_CONDITIONAL(POLL, [test "x$ac_cv_func_poll" = "xyes"]) + + AC_CHECK_LIB([bsd], [arc4random_buf]) +-AC_CHECK_FUNCS([arc4random_buf]) ++AC_CHECK_FUNCS([arc4random_buf getentropy]) + + AC_CHECK_DECLS([program_invocation_short_name], [], [], [[#include ]]) + +Index: xorg-server-1.19.3/include/dix-config.h.in +=================================================================== +--- xorg-server-1.19.3.orig/include/dix-config.h.in ++++ xorg-server-1.19.3/include/dix-config.h.in +@@ -167,6 +167,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 + +@@ -244,6 +247,9 @@ + /* Define to 1 if you have the header file. */ + #undef HAVE_SYS_UTSNAME_H + ++/* Define to 1 if you have the header file. */ ++#undef HAVE_SYS_SYSCALL_H ++ + /* Define to 1 if you have the `timingsafe_memcmp' function. */ + #undef HAVE_TIMINGSAFE_MEMCMP + +Index: xorg-server-1.19.3/os/auth.c +=================================================================== +--- xorg-server-1.19.3.orig/os/auth.c ++++ xorg-server-1.19.3/os/auth.c +@@ -48,6 +48,10 @@ from The Open Group. + #ifdef HAVE_LIBBSD + #include /* for arc4random_buf() */ + #endif ++#include ++#ifdef HAVE_SYS_SYSCALL_H ++#include ++#endif + + struct protocol { + unsigned short name_length; +@@ -302,18 +306,142 @@ GenerateAuthorization(unsigned name_leng + return -1; + } + ++#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 + } + + #endif /* XCSECURITY */ diff --git a/xorg-x11-server.changes b/xorg-x11-server.changes index d873308..bf97ffd 100644 --- a/xorg-x11-server.changes +++ b/xorg-x11-server.changes @@ -1,3 +1,19 @@ +------------------------------------------------------------------- +Thu Jul 13 13:20:07 UTC 2017 - sndirsch@suse.com + +- u_Use-better-fallbacks-to-generate-cookies-if-arc4rand.patch + 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 + (bsc#1025084) + ------------------------------------------------------------------- Fri Jul 7 09:13:23 UTC 2017 - msrb@suse.com diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index 771811f..58be0fa 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -206,6 +206,7 @@ Patch211: U_Xi-Do-not-try-to-swap-GenericEvent.patch Patch212: U_Xi-Verify-all-events-in-ProcXSendExtensionEvent.patch Patch213: U_Xi-Zero-target-buffer-in-SProcXSendExtensionEvent.patch Patch214: U_dix-Disallow-GenericEvent-in-SendEvent-request.patch +Patch215: u_Use-better-fallbacks-to-generate-cookies-if-arc4rand.patch Patch1000: n_xserver-optimus-autoconfig-hack.patch @@ -342,6 +343,7 @@ sh %{SOURCE92} --verify . %{SOURCE91} %patch212 -p1 %patch213 -p1 %patch214 -p1 +%patch215 -p1 ### disabled for now #%patch1000 -p1