From 6c2ba8d2215b27eeeb16e8b41f9b8497f384f593 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 15 Aug 2019 14:39:26 +0200 Subject: [PATCH 1/3] tools: make code cache and snapshot deterministic Use a fixed random seed to ensure that the generated sources are identical across runs. The final node binary still reseeds itself on start-up so there should be no security implications caused by predictable random numbers (e.g., `Math.random()`, ASLR, the hash seed, etc.) Fixes: https://github.com/nodejs/node/issues/29108 --- tools/code_cache/mkcodecache.cc | 2 ++ tools/snapshot/node_mksnapshot.cc | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tools/code_cache/mkcodecache.cc b/tools/code_cache/mkcodecache.cc index defa1462ce45ec..bc45d46a43b6cd 100644 --- a/tools/code_cache/mkcodecache.cc +++ b/tools/code_cache/mkcodecache.cc @@ -26,6 +26,8 @@ int wmain(int argc, wchar_t* argv[]) { int main(int argc, char* argv[]) { #endif // _WIN32 + v8::V8::SetFlagsFromString("--random_seed=42"); + if (argc < 2) { std::cerr << "Usage: " << argv[0] << " \n"; return 1; diff --git a/tools/snapshot/node_mksnapshot.cc b/tools/snapshot/node_mksnapshot.cc index f52cccb705f53a..29f9e1cbcbb096 100644 --- a/tools/snapshot/node_mksnapshot.cc +++ b/tools/snapshot/node_mksnapshot.cc @@ -19,6 +19,8 @@ int wmain(int argc, wchar_t* argv[]) { int main(int argc, char* argv[]) { #endif // _WIN32 + v8::V8::SetFlagsFromString("--random_seed=42"); + if (argc < 2) { std::cerr << "Usage: " << argv[0] << " \n"; return 1; From 4d9611c5852317784032634ddfef1eb286b03ce3 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 15 Aug 2019 14:56:37 +0200 Subject: [PATCH 2/3] fixup! add Math.random() regression test --- test/parallel/test-math-random.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 test/parallel/test-math-random.js diff --git a/test/parallel/test-math-random.js b/test/parallel/test-math-random.js new file mode 100644 index 00000000000000..bfa3335f7fc5db --- /dev/null +++ b/test/parallel/test-math-random.js @@ -0,0 +1,17 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); +const { spawnSync } = require('child_process'); + +const results = new Set(); +for (let i = 0; i < 10; i++) { + const result = spawnSync(process.execPath, ['-p', 'Math.random()']); + assert.strictEqual(result.status, 0); + results.add(result.stdout.toString()); +} +// It's theoretically possible if _very_ unlikely to see some duplicates. +// Therefore, don't expect that the size of the set is exactly 10 but do +// assume it's > 1 because if you get 10 duplicates in a row you should +// go out real quick and buy some lottery tickets, you lucky devil you! +assert(results.size > 1); From ed2c673fb75bd617b43bfb8b0953b2dda48bfc75 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 15 Aug 2019 16:35:10 +0200 Subject: [PATCH 3/3] fixup! fix parallel/test-code-cache test --- tools/code_cache/mkcodecache.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/code_cache/mkcodecache.cc b/tools/code_cache/mkcodecache.cc index bc45d46a43b6cd..e5b43a44b8d0d6 100644 --- a/tools/code_cache/mkcodecache.cc +++ b/tools/code_cache/mkcodecache.cc @@ -55,6 +55,9 @@ int main(int argc, char* argv[]) { v8::Local context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); + // The command line flags are part of the code cache's checksum so reset + // --random_seed= to its default value before creating the code cache. + v8::V8::SetFlagsFromString("--random_seed=0"); std::string cache = CodeCacheBuilder::Generate(context); out << cache; out.close();