Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:Update
libXdmcp
U_Use-getentropy-if-arc4random_buf-is-not-avail...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File U_Use-getentropy-if-arc4random_buf-is-not-available.patch of Package libXdmcp
From 0554324ec6bbc2071f5d1f8ad211a1643e29eb1f Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires <benjamin.tissoires@gmail.com> Date: Tue, 4 Apr 2017 19:13:38 +0200 Subject: [PATCH] Use getentropy() if arc4random_buf() is not available This allows to fix CVE-2017-2625 on Linux platforms without pulling in libbsd. The libc getentropy() is available since glibc 2.25 but also on OpenBSD. For Linux, we need at least a v3.17 kernel. If the recommended arc4random_buf() function is not available, emulate it by first trying to use getentropy() on a supported glibc and kernel. If the call fails, fall back to the current (vulnerable) code. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com> Reviewed-by: Mark Kettenis <kettenis@openbsd.org> Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> --- Key.c | 31 ++++++++++++++++++++++++++----- configure.ac | 2 +- 2 files changed, 27 insertions(+), 6 deletions(-) Index: libXdmcp-1.1.1/Key.c =================================================================== --- libXdmcp-1.1.1.orig/Key.c +++ libXdmcp-1.1.1/Key.c @@ -62,10 +62,11 @@ getbits (long data, unsigned char *dst) #define getpid(x) _getpid(x) #endif -void -XdmcpGenerateKey (XdmAuthKeyPtr key) -{ #ifndef HAVE_ARC4RANDOM_BUF + +static void +emulate_getrandom_buf (char *auth, int len) +{ long lowbits, highbits; srandom ((int)getpid() ^ time((Time_t *)0)); @@ -73,9 +74,152 @@ XdmcpGenerateKey (XdmAuthKeyPtr key) highbits = random (); getbits (lowbits, key->data); getbits (highbits, key->data + 4); +} + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE // needed on SLE11 for O_CLOEXEC +#endif +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <linux/random.h> +#include <sys/syscall.h> + +int getentropy_urandom(void *buffer, size_t length) +{ + int random_fd = -1; + ssize_t res = -1; + size_t filled = 0; + + 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; + + close(random_fd); + return -1; + } + else if( res == 0 ) + { + // no more bytes available? should not happen + errno = EIO; + close(random_fd); + return -1; + } + + filled += res; + } + + close(random_fd); + return 0; +} + +int getentropy_getrandom(void *buffer, size_t length) +{ + int res; + size_t filled = 0; + + if( length > 256 ) + { + errno = EIO; + return -1; + } + + while( filled < length ) + { +#ifdef SYS_getrandom + /* + * glibc does not contain a syscall wrapper for this in older + * versions + */ + res = syscall(SYS_getrandom, (char*)buffer + filled, length - filled, 0); #else +# warning no getrandom + errno = ENOSYS; + return -1; +#endif // SYS_getrandom + + 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; +} + +int getentropy_emulate(void *buffer, size_t length) +{ + /* + * check at runtime whether we have a getrandom system call available, + * otherwise fall back to urandom approach. autoconf check for + * getrandom() does not work, because there's been no declaration for + * it for years. + */ + int res = getentropy_getrandom(buffer, length); + + if( res == -1 && errno == ENOSYS ) + { + return getentropy_urandom(buffer, length); + } + + return res; +} + +static void +arc4random_buf (void *auth, int len) +{ + int ret; + +#if HAVE_GETENTROPY + /* weak emulation of arc4random through the getentropy libc call */ + ret = getentropy (auth, len); +#else + ret = getentropy_emulate (auth, len); +#endif /* HAVE_GETENTROPY */ + if (ret == 0) + return; + + emulate_getrandom_buf (auth, len); +} + +#endif /* !defined(HAVE_ARC4RANDOM_BUF) */ + +void +XdmcpGenerateKey (XdmAuthKeyPtr key) +{ arc4random_buf(key->data, 8); -#endif } int Index: libXdmcp-1.1.1/configure.ac =================================================================== --- libXdmcp-1.1.1.orig/configure.ac +++ libXdmcp-1.1.1/configure.ac @@ -58,7 +58,7 @@ AC_SEARCH_LIBS([recvfrom],[socket]) # Checks for library functions. AC_CHECK_LIB([bsd], [arc4random_buf]) -AC_CHECK_FUNCS([srand48 lrand48 arc4random_buf]) +AC_CHECK_FUNCS([srand48 lrand48 arc4random_buf getentropy]) # Obtain compiler/linker options for depedencies PKG_CHECK_MODULES(XDMCP, xproto)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor