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 499094 b283e9a224e0450ff9880af7b7366f9e73661ac5
parent 499093 f99c22e6f6b1e8820eb20936aee362dc86dbd454
child 499095 9f15c79e58d135c7e710210a9d0242eb42d9f5bc
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1402282
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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]