From: Paul Eggert <eggert@cs.ucla.edu>
To: Eli Zaretskii <eliz@gnu.org>
Cc: Richard Copley <rcopley@gmail.com>,
22202@debbugs.gnu.org, demetriobenour@gmail.com,
deng@randomsample.de
Subject: bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems
Date: Sun, 17 Jan 2016 12:26:31 -0800 [thread overview]
Message-ID: <569BF8F7.3090904@cs.ucla.edu> (raw)
In-Reply-To: <87h9jg5ay2.fsf@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 743 bytes --]
Eli, thanks for improving the initial seed for (random t) in Emacs. I noticed
that with this change, my Emacs was opening /dev/urandom twice, because GnuTLS
does something similar during startup. Also, it was reading more data from
/dev/urandom than it needed, due to stdio buffering. So I installed the attached
patch, which defers to GnuTLS and falls back on doing things by hand (without
stdio) only if GnuTLS is not available or fails. I assume this approach works
under MS-Windows; if not please let me know and I'll try to fix it.
Would you mind if I removed the newly-added details about current time and
process ID from the documentation? The idea is that this is internal
implementation detail that users should not rely on.
[-- Attachment #2: 0001-Prefer-GnuTLS-when-acquiring-random-seed.patch --]
[-- Type: text/x-diff, Size: 4807 bytes --]
From 05e8148a24ebe51fbe758dd16265e8fb81f85953 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Sun, 17 Jan 2016 12:12:08 -0800
Subject: [PATCH] Prefer GnuTLS when acquiring random seed
This attempts to improve on the fix for Bug#22202.
* configure.ac (HAVE_DEV_URANDOM): Remove.
Check /dev/urandom existence at run time, not at build time,
since the device could exist in the former but not the latter.
* src/sysdep.c [HAVE_GNUTLS]: Include gnutls/gnutls.h.
(gnutls_rnd) [GNUTLS_VERSION_NUMBER < 0x020c00]: New fallback macro.
(random_seed): New typedef.
(set_random_seed): New static function.
(seed_random): Use them.
(init_random): Use random_seed instead of uintmax_t, so as to
not consume more entropy than needed. Prefer gnutls_rnd if it
works; this avoids a redundant open of /dev/urandom on
GNU/Linux with modern GnuTLS.
---
configure.ac | 16 ------------
src/sysdep.c | 85 ++++++++++++++++++++++++++++++------------------------------
2 files changed, 43 insertions(+), 58 deletions(-)
diff --git a/configure.ac b/configure.ac
index 6c9b621..8c01aba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4153,22 +4153,6 @@ fi
AC_TYPE_MBSTATE_T
-AC_MSG_CHECKING([whether "/dev/urandom" is available])
-dev_urandom=no
-dnl MSYS, being a Cygwin fork, thinks "/dev/urandom" does exist, so
-dnl don't check this for the MinGW builds.
-if test "${opsys}" != "mingw32"; then
- if test -r "/dev/urandom"; then
- AC_DEFINE(HAVE_DEV_URANDOM, 1, [Define if the system supports the "/dev/urandom" device.])
- dev_urandom=yes
- fi
-fi
-if test $dev_urandom = yes; then
- AC_MSG_RESULT(yes)
-else
- AC_MSG_RESULT(no)
-fi
-
dnl Fixme: AC_SYS_POSIX_TERMIOS should probably be used, but it's not clear
dnl how the tty code is related to POSIX and/or other versions of termios.
dnl The following looks like a useful start.
diff --git a/src/sysdep.c b/src/sysdep.c
index 1fa4229..635443c 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -99,6 +99,15 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "process.h"
#include "cm.h"
+#ifdef HAVE_GNUTLS
+# include <gnutls/gnutls.h>
+#endif
+#if 0x020c00 <= GNUTLS_VERSION_NUMBER
+# include <gnutls/crypto.h>
+#else
+# define gnutls_rnd(level, data, len) (-1)
+#endif
+
#ifdef WINDOWSNT
#include <direct.h>
/* In process.h which conflicts with the local copy. */
@@ -2068,63 +2077,55 @@ init_signals (bool dumping)
# endif /* !HAVE_RANDOM */
#endif /* !RAND_BITS */
+#ifdef HAVE_RANDOM
+typedef unsigned int random_seed;
+static void set_random_seed (random_seed arg) { srandom (arg); }
+#elif defined HAVE_LRAND48
+/* Although srand48 uses a long seed, this is unsigned long to avoid
+ undefined behavior on signed integer overflow in init_random. */
+typedef unsigned long int random_seed;
+static void set_random_seed (random_seed arg) { srand48 (arg); }
+#else
+typedef unsigned int random_seed;
+static void set_random_seed (random_seed arg) { srand (arg); }
+#endif
+
void
seed_random (void *seed, ptrdiff_t seed_size)
{
-#if defined HAVE_RANDOM || ! defined HAVE_LRAND48
- unsigned int arg = 0;
-#else
- long int arg = 0;
-#endif
+ random_seed arg = 0;
unsigned char *argp = (unsigned char *) &arg;
unsigned char *seedp = seed;
- ptrdiff_t i;
- for (i = 0; i < seed_size; i++)
+ for (ptrdiff_t i = 0; i < seed_size; i++)
argp[i % sizeof arg] ^= seedp[i];
-#ifdef HAVE_RANDOM
- srandom (arg);
-#else
-# ifdef HAVE_LRAND48
- srand48 (arg);
-# else
- srand (arg);
-# endif
-#endif
+ set_random_seed (arg);
}
void
init_random (void)
{
- uintmax_t v;
- struct timespec t;
- bool success = false;
-
-#if HAVE_DEV_URANDOM
- FILE *fp = fopen ("/dev/urandom", "rb");
-
- if (fp)
+ random_seed v;
+ if (gnutls_rnd (GNUTLS_RND_NONCE, &v, sizeof v) != 0)
{
- int i;
-
- for (i = 0, v = 0; i < sizeof (uintmax_t); i++)
+ bool success = false;
+#ifndef WINDOWSNT
+ int fd = emacs_open ("/dev/urandom", O_RDONLY | O_BINARY, 0);
+ if (0 <= fd)
{
- v <<= 8;
- v |= fgetc (fp);
+ success = emacs_read (fd, &v, sizeof v) == sizeof v;
+ emacs_close (fd);
+ }
+#else
+ success = w32_init_random (&v, sizeof v) == 0;
+#endif
+ if (! success)
+ {
+ /* Fall back to current time value + PID. */
+ struct timespec t = current_timespec ();
+ v = getpid () ^ t.tv_sec ^ t.tv_nsec;
}
- fclose (fp);
- success = true;
- }
-#elif defined WINDOWSNT
- if (w32_init_random (&v, sizeof v) == 0)
- success = true;
-#endif /* HAVE_DEV_URANDOM || WINDOWSNT */
- if (!success)
- {
- /* Fall back to current time value + PID. */
- t = current_timespec ();
- v = getpid () ^ t.tv_sec ^ t.tv_nsec;
}
- seed_random (&v, sizeof v);
+ set_random_seed (v);
}
/*
--
2.5.0
next prev parent reply other threads:[~2016-01-17 20:26 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-18 10:05 bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems Demetri Obenour
2015-12-18 10:46 ` Eli Zaretskii
2015-12-29 15:36 ` Richard Copley
2015-12-29 16:21 ` Eli Zaretskii
2015-12-29 17:44 ` Richard Copley
2015-12-29 20:00 ` David Engster
2015-12-29 21:22 ` Richard Copley
2015-12-29 22:02 ` David Engster
2015-12-29 23:13 ` Richard Copley
2015-12-30 15:58 ` Eli Zaretskii
2015-12-30 20:47 ` Richard Copley
2015-12-30 20:56 ` Richard Copley
2015-12-30 20:56 ` Eli Zaretskii
2015-12-30 21:15 ` Richard Copley
2015-12-31 14:14 ` Eli Zaretskii
2015-12-31 17:04 ` Demetrios Obenour
2015-12-31 17:24 ` Eli Zaretskii
2015-12-31 17:47 ` Richard Copley
2015-12-31 18:22 ` Eli Zaretskii
2015-12-31 19:20 ` Eli Zaretskii
2015-12-31 19:49 ` Richard Copley
2015-12-31 20:13 ` Eli Zaretskii
2015-12-31 20:44 ` Richard Copley
2016-01-15 9:55 ` Eli Zaretskii
2016-01-17 20:26 ` Paul Eggert [this message]
2016-01-18 1:42 ` Paul Eggert
2016-01-18 14:40 ` Richard Copley
2016-01-18 16:05 ` Eli Zaretskii
2016-01-18 16:20 ` Richard Copley
2016-01-18 15:45 ` Eli Zaretskii
2016-01-18 20:50 ` Paul Eggert
2016-01-18 21:09 ` Eli Zaretskii
2016-01-19 5:34 ` Paul Eggert
2016-01-19 16:24 ` Eli Zaretskii
2016-01-19 17:03 ` John Wiegley
2016-01-19 17:38 ` Paul Eggert
2016-01-19 18:44 ` Eli Zaretskii
2016-01-19 17:07 ` Paul Eggert
2016-01-19 18:16 ` Eli Zaretskii
2016-01-20 0:39 ` Paul Eggert
2016-01-18 12:04 ` Andy Moreton
2016-01-18 15:57 ` Eli Zaretskii
2016-01-18 23:03 ` John Wiegley
2016-01-19 21:48 ` Andy Moreton
2016-01-20 3:31 ` Glenn Morris
2016-01-20 14:06 ` Andy Moreton
2016-01-20 14:12 ` Eli Zaretskii
2016-01-20 15:15 ` Andy Moreton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=569BF8F7.3090904@cs.ucla.edu \
--to=eggert@cs.ucla.edu \
--cc=22202@debbugs.gnu.org \
--cc=demetriobenour@gmail.com \
--cc=deng@randomsample.de \
--cc=eliz@gnu.org \
--cc=rcopley@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.