Bug 1402282 - Move CSPRNG logic to common area r=froydnj
☠☠ backed out by 9f15c79e58d1 ☠ ☠
authorCosmin Sabou <csabou@mozilla.com>
Wed, 24 Oct 2018 02:49:33 +0300
changeset 491033 b283e9a224e0450ff9880af7b7366f9e73661ac5
parent 491032 f99c22e6f6b1e8820eb20936aee362dc86dbd454
child 491034 9f15c79e58d135c7e710210a9d0242eb42d9f5bc
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersfroydnj
bugs1402282
milestone65.0a1
Bug 1402282 - Move CSPRNG logic to common area r=froydnj
js/src/jsmath.cpp
mfbt/moz.build
mfbt/tests/moz.build
testing/cppunittest.ini
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -8,117 +8,51 @@
  * JS math package.
  */
 
 #include "jsmath.h"
 
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/MemoryReporting.h"
+#include "mozilla/RandomNum.h"
 #include "mozilla/Unused.h"
 #include "mozilla/WrappingOperations.h"
 
 #include <cmath>
-#include <fcntl.h>
-#ifdef XP_UNIX
-# include <unistd.h>
-#endif
 
 #include "fdlibm.h"
 #include "jsapi.h"
 #include "jstypes.h"
 
 #include "jit/InlinableNatives.h"
 #include "js/Class.h"
 #include "util/Windows.h"
 #include "vm/JSAtom.h"
 #include "vm/JSContext.h"
 #include "vm/Realm.h"
 #include "vm/Time.h"
 
 #include "vm/JSObject-inl.h"
 
-#if defined(XP_WIN)
-// #define needed to link in RtlGenRandom(), a.k.a. SystemFunction036.  See the
-// "Community Additions" comment on MSDN here:
-// https://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx
-# define SystemFunction036 NTAPI SystemFunction036
-# include <ntsecapi.h>
-# undef SystemFunction036
-#endif
-
-#if defined(ANDROID) || defined(XP_DARWIN) || defined(__DragonFly__) || \
-    defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
-# include <stdlib.h>
-# define HAVE_ARC4RANDOM
-#endif
-
-#if defined(__linux__)
-# include <linux/random.h> // For GRND_NONBLOCK.
-# include <sys/syscall.h> // For SYS_getrandom.
-
-// Older glibc versions don't define SYS_getrandom, so we define it here if
-// it's not available. See bug 995069.
-# if defined(__x86_64__)
-#  define GETRANDOM_NR 318
-# elif defined(__i386__)
-#  define GETRANDOM_NR 355
-# elif defined(__aarch64__)
-#  define GETRANDOM_NR 278
-# elif defined(__arm__)
-#  define GETRANDOM_NR 384
-# elif defined(__powerpc__)
-#  define GETRANDOM_NR 359
-# elif defined(__s390__)
-#  define GETRANDOM_NR 349
-# elif defined(__mips__)
-#  include <sgidefs.h>
-#  if _MIPS_SIM == _MIPS_SIM_ABI32
-#    define GETRANDOM_NR 4353
-#  elif _MIPS_SIM == _MIPS_SIM_ABI64
-#    define GETRANDOM_NR 5313
-#  elif _MIPS_SIM == _MIPS_SIM_NABI32
-#    define GETRANDOM_NR 6317
-#  endif
-# endif
-
-# if defined(SYS_getrandom)
-// We have SYS_getrandom. Use it to check GETRANDOM_NR. Only do this if we set
-// GETRANDOM_NR so tier 3 platforms with recent glibc are not forced to define
-// it for no good reason.
-#  if defined(GETRANDOM_NR)
-static_assert(GETRANDOM_NR == SYS_getrandom,
-              "GETRANDOM_NR should match the actual SYS_getrandom value");
-#  endif
-# else
-#  define SYS_getrandom GETRANDOM_NR
-# endif
-
-# if defined(GRND_NONBLOCK)
-static_assert(GRND_NONBLOCK == 1, "If GRND_NONBLOCK is not 1 the #define below is wrong");
-# else
-#  define GRND_NONBLOCK 1
-# endif
-
-#endif // defined(__linux__)
-
 using namespace js;
 
 using mozilla::Abs;
-using mozilla::NumberEqualsInt32;
-using mozilla::NumberIsInt32;
 using mozilla::ExponentComponent;
 using mozilla::FloatingPoint;
 using mozilla::IsFinite;
 using mozilla::IsInfinite;
 using mozilla::IsNaN;
 using mozilla::IsNegative;
 using mozilla::IsNegativeZero;
+using mozilla::Maybe;
+using mozilla::NegativeInfinity;
+using mozilla::NumberEqualsInt32;
+using mozilla::NumberIsInt32;
 using mozilla::PositiveInfinity;
-using mozilla::NegativeInfinity;
 using mozilla::WrappingMultiply;
 using JS::ToNumber;
 using JS::GenericNaN;
 
 static const JSConstDoubleSpec math_constants[] = {
     // clang-format off
     {"E"      ,  M_E       },
     {"LOG2E"  ,  M_LOG2E   },
@@ -629,45 +563,23 @@ js::math_pow(JSContext* cx, unsigned arg
     double z = ecmaPow(x, y);
     args.rval().setNumber(z);
     return true;
 }
 
 uint64_t
 js::GenerateRandomSeed()
 {
-    uint64_t seed = 0;
-
-#if defined(XP_WIN)
-    MOZ_ALWAYS_TRUE(RtlGenRandom(&seed, sizeof(seed)));
-#elif defined(HAVE_ARC4RANDOM)
-    seed = (static_cast<uint64_t>(arc4random()) << 32) | arc4random();
-#elif defined(XP_UNIX)
-    bool done = false;
-# if defined(__linux__)
-    // Try the relatively new getrandom syscall first. It's the preferred way
-    // on Linux as /dev/urandom may not work inside chroots and is harder to
-    // sandbox (see bug 995069).
-    int ret = syscall(SYS_getrandom, &seed, sizeof(seed), GRND_NONBLOCK);
-    done = (ret == sizeof(seed));
-# endif
-    if (!done) {
-        int fd = open("/dev/urandom", O_RDONLY);
-        if (fd >= 0) {
-            mozilla::Unused << read(fd, static_cast<void*>(&seed), sizeof(seed));
-            close(fd);
-        }
-    }
-#else
-# error "Platform needs to implement GenerateRandomSeed()"
-#endif
-
-    // Also mix in PRMJ_Now() in case we couldn't read random bits from the OS.
-    uint64_t timestamp = PRMJ_Now();
-    return seed ^ timestamp ^ (timestamp << 32);
+    Maybe<uint64_t> maybeSeed = mozilla::RandomUint64();
+    
+    return maybeSeed.valueOrFrom([] {
+        // Use PRMJ_Now() in case we couldn't read random bits from the OS.
+        uint64_t timestamp = PRMJ_Now();
+        return timestamp ^ (timestamp << 32);
+    });
 }
 
 void
 js::GenerateXorShift128PlusSeed(mozilla::Array<uint64_t, 2>& seed)
 {
     // XorShift128PlusRNG must be initialized with a non-zero seed.
     do {
         seed[0] = GenerateRandomSeed();
--- a/mfbt/moz.build
+++ b/mfbt/moz.build
@@ -64,16 +64,17 @@ EXPORTS.mozilla = [
     'NotNull.h',
     'NullPtr.h',
     'Opaque.h',
     'OperatorNewExtensions.h',
     'Pair.h',
     'Path.h',
     'PodOperations.h',
     'Poison.h',
+    'RandomNum.h',
     'Range.h',
     'RangedArray.h',
     'RangedPtr.h',
     'RecordReplay.h',
     'ReentrancyGuard.h',
     'RefCounted.h',
     'RefCountType.h',
     'RefPtr.h',
@@ -142,16 +143,17 @@ UNIFIED_SOURCES += [
     'double-conversion/double-conversion/double-conversion.cc',
     'double-conversion/double-conversion/fast-dtoa.cc',
     'double-conversion/double-conversion/fixed-dtoa.cc',
     'double-conversion/double-conversion/strtod.cc',
     'FloatingPoint.cpp',
     'HashFunctions.cpp',
     'JSONWriter.cpp',
     'Poison.cpp',
+    'RandomNum.cpp',
     'RecordReplay.cpp',
     'SHA1.cpp',
     'TaggedAnonymousMemory.cpp',
     'Unused.cpp',
     'Utf8.cpp',
 ]
 
 DEFINES['IMPL_MFBT'] = True
--- a/mfbt/tests/moz.build
+++ b/mfbt/tests/moz.build
@@ -39,16 +39,17 @@ CppUnitTests([
     'TestLinkedList',
     'TestMacroArgs',
     'TestMacroForEach',
     'TestMathAlgorithms',
     'TestMaybe',
     'TestNonDereferenceable',
     'TestNotNull',
     'TestPair',
+    'TestRandomNum',
     'TestRange',
     'TestRefPtr',
     'TestResult',
     'TestRollingMean',
     'TestSaturate',
     'TestScopeExit',
     'TestSegmentedVector',
     'TestSHA1',
--- a/testing/cppunittest.ini
+++ b/testing/cppunittest.ini
@@ -34,16 +34,17 @@ skip-if = os != 'win'
 [TestMaybe]
 [TestNonDereferenceable]
 [TestNotNull]
 [TestParseFTPList]
 [TestPLDHash]
 [TestPair]
 [TestPoisonArea]
 skip-if = os == 'android' # Bug 1147630
+[TestRandomNum]
 [TestRange]
 [TestRefPtr]
 [TestResult]
 [TestRollingMean]
 [TestScopeExit]
 [TestSegmentedVector]
 [TestSHA1]
 [TestSmallPointerArray]