Bug 1376819 Reuse the file descriptor in js::GenerateRandomSeed on Linux to avoid re-opening it WIP draft
authorTom Ritter <tom@mozilla.com>
Fri, 27 Oct 2017 15:49:36 -0500
changeset 697249 237448e56f9cc25d8959b8f2ac4e5ce07ffa173e
parent 697248 779b5b534c6c19ee3c913399cf7c88395af245a0
child 740058 48a38bc3ef72dc28cb376a1b7cff3a95bb777528
push id88934
push userbmo:tom@mozilla.com
push dateMon, 13 Nov 2017 17:15:30 +0000
bugs1376819
milestone58.0a1
Bug 1376819 Reuse the file descriptor in js::GenerateRandomSeed on Linux to avoid re-opening it WIP MozReview-Commit-ID: 4mje1dcIX2l
js/src/jsmath.cpp
old mode 100644
new mode 100755
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -742,16 +742,20 @@ js::math_pow_handle(JSContext* cx, Handl
 bool
 js::math_pow(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     return math_pow_handle(cx, args.get(0), args.get(1), args.rval());
 }
 
+# if defined(__linux__)
+int rngFD = 0;
+# endif
+
 uint64_t
 js::GenerateRandomSeed()
 {
     uint64_t seed = 0;
 
 #if defined(XP_WIN)
     MOZ_ALWAYS_TRUE(RtlGenRandom(&seed, sizeof(seed)));
 #elif defined(HAVE_ARC4RANDOM)
@@ -761,20 +765,21 @@ js::GenerateRandomSeed()
 # 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);
+        if (rngFD == 0) {
+            rngFD = open("/dev/urandom", O_RDONLY);
+        }
+        if (rngFD >= 0) {
+            mozilla::Unused << read(rngFD, static_cast<void*>(&seed), sizeof(seed));
         }
     }
 #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();