Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.3
libICE
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 libICE
From ff5e59f32255913bb1cdf51441b98c9107ae165b Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires <benjamin.tissoires@gmail.com> Date: Tue, 4 Apr 2017 19:12:53 +0200 Subject: [PATCH] Use getentropy() if arc4random_buf() is not available This allows to fix CVE-2017-2626 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 (partly 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> --- configure.ac | 2 +- src/iceauth.c | 65 ++++++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 47 insertions(+), 20 deletions(-) Index: libICE-1.0.9/configure.ac =================================================================== --- libICE-1.0.9.orig/configure.ac +++ libICE-1.0.9/configure.ac @@ -38,7 +38,7 @@ AC_DEFINE(ICE_t, 1, [Xtrans transport ty # Checks for library functions. AC_CHECK_LIB([bsd], [arc4random_buf]) -AC_CHECK_FUNCS([asprintf arc4random_buf]) +AC_CHECK_FUNCS([asprintf arc4random_buf getentropy]) # Allow checking code with lint, sparse, etc. XORG_WITH_LINT Index: libICE-1.0.9/src/iceauth.c =================================================================== --- libICE-1.0.9.orig/src/iceauth.c +++ libICE-1.0.9/src/iceauth.c @@ -42,31 +42,19 @@ Author: Ralph Mor, X Consortium static int was_called_state; -/* - * MIT-MAGIC-COOKIE-1 is a sample authentication method implemented by - * the SI. It is not part of standard ICElib. - */ +#ifndef HAVE_ARC4RANDOM_BUF - -char * -IceGenerateMagicCookie ( +static void +emulate_getrandom_buf ( + char *auth, int len ) { - char *auth; -#ifndef HAVE_ARC4RANDOM_BUF long ldata[2]; int seed; int value; int i; -#endif - - if ((auth = malloc (len + 1)) == NULL) - return (NULL); -#ifdef HAVE_ARC4RANDOM_BUF - arc4random_buf(auth, len); -#else #ifdef ITIMER_REAL { struct timeval now; @@ -74,13 +62,13 @@ IceGenerateMagicCookie ( ldata[0] = now.tv_sec; ldata[1] = now.tv_usec; } -#else +#else /* ITIMER_REAL */ { long time (); ldata[0] = time ((long *) 0); ldata[1] = getpid (); } -#endif +#endif /* ITIMER_REAL */ seed = (ldata[0]) + (ldata[1] << 16); srand (seed); for (i = 0; i < len; i++) @@ -88,7 +76,169 @@ IceGenerateMagicCookie ( value = rand (); auth[i] = value & 0xff; } +} + +#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 ( + char *auth, + int len +) +{ + int ret; + +#if HAVE_GETENTROPY + /* weak emulation of arc4random through the entropy libc */ + 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) */ + +/* + * MIT-MAGIC-COOKIE-1 is a sample authentication method implemented by + * the SI. It is not part of standard ICElib. + */ + + +char * +IceGenerateMagicCookie ( + int len +) +{ + char *auth; + + if ((auth = malloc (len + 1)) == NULL) + return (NULL); + + arc4random_buf (auth, len); + auth[len] = '\0'; return (auth); }
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