[PATCH libICE] Use getrandom() syscall if available

Benjamin Tissoires benjamin.tissoires at gmail.com
Mon Apr 3 12:56:49 UTC 2017


This allows to fix CVE-2017-2626 on Linux platforms without pulling in
libbsd.
The syscall getrandom is available since kernel v3.17. The code first
tries to use the syscall on a supported kernel. If the syscall fails,
it falls back to the current (partly vulnerable) code.
We do not implement the glibc getrandom() call given that it's only
available in glibc 2.25, and the #if dance is already messy here.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires at gmail.com>
---
 configure.ac  |  3 +++
 src/iceauth.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 65 insertions(+), 17 deletions(-)

diff --git a/configure.ac b/configure.ac
index 458882a..33d7381 100644
--- a/configure.ac
+++ b/configure.ac
@@ -36,6 +36,9 @@ PKG_CHECK_MODULES(ICE, xproto xtrans)
 XTRANS_CONNECTION_FLAGS
 AC_DEFINE(ICE_t, 1, [Xtrans transport type])
 
+# Checks for syscalls
+AC_CHECK_DECLS([SYS_getrandom], [], [], [[#include <sys/syscall.h>]])
+
 # Checks for library functions.
 AC_CHECK_LIB([bsd], [arc4random_buf])
 AC_CHECK_FUNCS([asprintf arc4random_buf])
diff --git a/src/iceauth.c b/src/iceauth.c
index ed31683..8b83168 100644
--- a/src/iceauth.c
+++ b/src/iceauth.c
@@ -40,35 +40,26 @@ Author: Ralph Mor, X Consortium
 #include <bsd/stdlib.h>	/* for arc4random_buf() */
 #endif
 
+#if HAVE_DECL_SYS_GETRANDOM
+#include <sys/syscall.h> /* for SYS_getrandom */
+#endif
+
 #include <unistd.h>
 
 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.
- */
-
-
-char *
-IceGenerateMagicCookie (
+#ifndef HAVE_ARC4RANDOM_BUF
+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;
@@ -90,7 +81,61 @@ IceGenerateMagicCookie (
 	value = rand ();
 	auth[i] = value & 0xff;
     }
+}
+#endif
+
+#ifdef HAVE_ARC4RANDOM_BUF
+static inline void
+getrandom_buf (
+	char *auth,
+	int len
+)
+{
+    arc4random_buf(auth, len);
+}
+#elif HAVE_DECL_SYS_GETRANDOM
+static void
+getrandom_buf (
+	char *auth,
+	int len
+)
+{
+    int	    ret;
+
+    ret = syscall(SYS_getrandom, auth, len, 0);
+    if (ret != len)
+	emulate_getrandom_buf(auth, len);
+}
+#else
+static inline void
+getrandom_buf (
+	char *auth,
+	int len
+)
+{
+	emulate_getrandom_buf(auth, len);
+}
 #endif
+
+
+/*
+ * 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);
+
+    getrandom_buf(auth, len);
+
     auth[len] = '\0';
     return (auth);
 }
-- 
2.9.3



More information about the xorg-devel mailing list