[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random num
From: |
Eli Zaretskii |
Subject: |
bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems |
Date: |
Thu, 31 Dec 2015 16:14:00 +0200 |
> Date: Wed, 30 Dec 2015 21:15:13 +0000
> From: Richard Copley <rcopley@gmail.com>
> Cc: David Engster <deng@randomsample.de>, 22202@debbugs.gnu.org,
> Demetri Obenour <demetriobenour@gmail.com>
>
> > That'd be the worst of both worlds, IMO: a not-so-good PRNG with no
> > way whatsoever to get a repeatable sequence. Am I right?
>
> Oh dear. Yes. Worse than that, repeatability is part of the contract for
> the lisp "random" function, so seed_random() and get_random() are
> constrained to be deterministic. Right?
>
> Seems as though init_random() is the only place that could use
> CryptGenRandom, which is a pity if you're trying to confine the
> changes to w32.c.
How about the following, then?
(Not sure it's a good idea to read from /dev/random, as that could
block; perhaps we should use /dev/urandom instead.)
--- src/sysdep.c~2 2015-11-11 07:57:41.000000000 +0200
+++ src/sysdep.c 2015-12-31 16:09:46.987229300 +0200
@@ -2095,8 +2095,35 @@ seed_random (void *seed, ptrdiff_t seed_
void
init_random (void)
{
- struct timespec t = current_timespec ();
- uintmax_t v = getpid () ^ t.tv_sec ^ t.tv_nsec;
+ uintmax_t v;
+ struct timespec t;
+ bool success = false;
+
+#if HAVE_DEV_RANDOM
+ FILE *fp = fopen ("/dev/random", "rb");
+
+ if (fp)
+ {
+ int i;
+
+ for (i = 0, v = 0; i < sizeof (uintmax_t); i++)
+ {
+ v <<= 8;
+ v |= fgetc (fp);
+ }
+ fclose (fp);
+ success = true;
+ }
+#elif defined WINDOWSNT
+ if (w32_init_random (&v, sizeof v) == 0)
+ success = true;
+#endif /* HAVE_DEV_RANDOM || 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);
}
--- src/w32.c~0 2015-11-29 06:48:07.000000000 +0200
+++ src/w32.c 2015-12-31 16:05:06.775707600 +0200
@@ -224,6 +224,8 @@ typedef struct _REPARSE_DATA_BUFFER {
#include <iphlpapi.h> /* should be after winsock2.h */
+#include <wincrypt.h>
+
#include <c-strcase.h>
#include "w32.h"
@@ -2093,6 +2095,34 @@ init_user_info (void)
CloseHandle (token);
}
+static HCRYPTPROV w32_crypto_hprov;
+static int
+w32_init_crypt_random (void)
+{
+ if (!CryptAcquireContext (&w32_crypto_hprov, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
+ {
+ DebPrint (("CryptAcquireContext failed with error %x\n",
+ GetLastError ()));
+ w32_crypto_hprov = 0;
+ return -1;
+ }
+ return 0;
+}
+
+int
+w32_init_random (void *buf, ptrdiff_t buflen)
+{
+ if (w32_crypto_hprov)
+ w32_init_crypt_random ();
+ if (w32_crypto_hprov)
+ {
+ if (CryptGenRandom (w32_crypto_hprov, buflen, (BYTE *)buf))
+ return 0;
+ }
+ return -1;
+}
+
int
random (void)
{
@@ -9386,6 +9416,8 @@ globals_of_w32 (void)
extern void dynlib_reset_last_error (void);
dynlib_reset_last_error ();
#endif
+
+ w32_crypto_hprov = (HCRYPTPROV)0;
}
/* For make-serial-process */
--- src/w32.h~2 2015-11-29 06:48:07.000000000 +0200
+++ src/w32.h 2015-12-31 16:09:21.960654500 +0200
@@ -222,6 +222,9 @@ extern int w32_memory_info (unsigned lon
/* Compare 2 UTF-8 strings in locale-dependent fashion. */
extern int w32_compare_strings (const char *, const char *, char *, int);
+/* Return a cryptographically secure seed for PRNG. */
+extern int w32_init_random (void *, ptrdiff_t);
+
#ifdef HAVE_GNUTLS
#include <gnutls/gnutls.h>
--- src/fns.c~ 2015-11-22 07:57:20.000000000 +0200
+++ src/fns.c 2015-12-31 16:57:43.607286800 +0200
@@ -50,7 +50,8 @@ All integers representable in Lisp, i.e.
and `most-positive-fixnum', inclusive, are equally likely.
With positive integer LIMIT, return random number in interval [0,LIMIT).
-With argument t, set the random number seed from the current time and pid.
+With argument t, set the random number seed from the system's entropy
+pool, or from the current time and pid if entropy is unavailable.
With a string argument, set the seed based on the string's contents.
Other values of LIMIT are ignored.
--- configure.ac~2 2015-12-20 06:45:33.000000000 +0200
+++ configure.ac 2015-12-31 16:06:48.959511800 +0200
@@ -4145,6 +4145,22 @@
AC_TYPE_MBSTATE_T
+AC_MSG_CHECKING([whether "/dev/random" is available])
+dev_random=no
+dnl MSYS, being a Cygwin fork, thinks "/dev/random" does exist, so
+dnl don't check this for the MinGW builds.
+if test "${opsys}" != "mingw32"; then
+ if test -r "/dev/random"; then
+ AC_DEFINE(HAVE_DEV_RANDOM, 1, [Define if the system supports the
"/dev/random" device.])
+ dev_random=yes
+ fi
+fi
+if test $dev_random = 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.
- bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems, (continued)
- bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems, Eli Zaretskii, 2015/12/29
- bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems, Richard Copley, 2015/12/29
- bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems, David Engster, 2015/12/29
- bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems, Richard Copley, 2015/12/29
- bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems, David Engster, 2015/12/29
- bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems, Richard Copley, 2015/12/29
- bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems, Eli Zaretskii, 2015/12/30
- bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems, Richard Copley, 2015/12/30
- bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems, Eli Zaretskii, 2015/12/30
- bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems, Richard Copley, 2015/12/30
- bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems,
Eli Zaretskii <=
- bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems, Richard Copley, 2015/12/30
- bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems, Demetrios Obenour, 2015/12/31
- bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems, Eli Zaretskii, 2015/12/31