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: 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(-) diff --git a/configure.ac b/configure.ac index 458882a..c971ab6 100644 --- a/configure.ac +++ b/configure.ac @@ -38,7 +38,7 @@ AC_DEFINE(ICE_t, 1, [Xtrans transport type]) # 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 diff --git a/src/iceauth.c b/src/iceauth.c index ed31683..de4785b 100644 --- a/src/iceauth.c +++ b/src/iceauth.c @@ -44,31 +44,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; @@ -76,13 +64,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++) @@ -90,7 +78,46 @@ IceGenerateMagicCookie ( value = rand (); auth[i] = value & 0xff; } -#endif +} + +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); + if (ret == 0) + return; +#endif /* HAVE_GETENTROPY */ + + 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); } -- cgit v1.1