diff options
-rw-r--r-- | content/app/content_main_runner.cc | 8 | ||||
-rw-r--r-- | gin/BUILD.gn | 36 | ||||
-rw-r--r-- | gin/DEPS | 1 | ||||
-rw-r--r-- | gin/fingerprint/fingerprint_v8_snapshot.gypi | 47 | ||||
-rwxr-xr-x | gin/fingerprint/fingerprint_v8_snapshot.py | 86 | ||||
-rw-r--r-- | gin/gin.gyp | 26 | ||||
-rw-r--r-- | gin/isolate_holder.cc | 43 | ||||
-rw-r--r-- | gin/public/isolate_holder.h | 2 |
8 files changed, 235 insertions, 14 deletions
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc index 05e45bd..2da7dc1 100644 --- a/content/app/content_main_runner.cc +++ b/content/app/content_main_runner.cc @@ -721,7 +721,7 @@ class ContentMainRunnerImpl : public ContentMainRunner { else CHECK(base::i18n::InitializeICU()); -#ifdef V8_USE_EXTERNAL_STARTUP_DATA +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) int v8_natives_fd = base::GlobalDescriptors::GetInstance()->MaybeGet( kV8NativesDataDescriptor); int v8_snapshot_fd = base::GlobalDescriptors::GetInstance()->MaybeGet( @@ -736,10 +736,10 @@ class ContentMainRunnerImpl : public ContentMainRunner { #else CHECK(base::i18n::InitializeICU()); -#ifdef V8_USE_EXTERNAL_STARTUP_DATA +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) CHECK(gin::IsolateHolder::LoadV8Snapshot()); -#endif // V8_USE_EXTERNAL_STARTUP_DATA -#endif // OS_ANDROID +#endif // V8_USE_EXTERNAL_STARTUP_DATA +#endif // OS_ANDROID InitializeStatsTable(command_line); diff --git a/gin/BUILD.gn b/gin/BUILD.gn index b352c3a..d389b84 100644 --- a/gin/BUILD.gn +++ b/gin/BUILD.gn @@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/module_args/v8.gni") + component("gin") { sources = [ "arguments.cc", @@ -68,6 +70,40 @@ component("gin") { deps = [ "//base/third_party/dynamic_annotations", ] + if (v8_use_external_startup_data && is_win) { + deps += [ + ":gin_v8_snapshot_fingerprint", + "//crypto:crypto", + ] + sources += [ "$target_gen_dir/v8_snapshot_fingerprint.cc" ] + defines += [ "V8_VERIFY_EXTERNAL_STARTUP_DATA" ] + } +} + +if (v8_use_external_startup_data) { + action("gin_v8_snapshot_fingerprint") { + script = "//gin/fingerprint/fingerprint_v8_snapshot.py" + + snapshot_file = "$root_build_dir/snapshot_blob.bin" + natives_file = "$root_build_dir/natives_blob.bin" + output_file = "$target_gen_dir/v8_snapshot_fingerprint.cc" + + args = [ + "--snapshot_file", + rebase_path(snapshot_file, root_build_dir), + "--natives_file", + rebase_path(natives_file, root_build_dir), + "--output_file", + rebase_path(output_file, root_build_dir), + ] + inputs = [ + snapshot_file, + natives_file, + ] + outputs = [ + output_file, + ] + } } executable("gin_shell") { @@ -1,4 +1,5 @@ include_rules = [ "+base", + "+crypto", "+v8", ] diff --git a/gin/fingerprint/fingerprint_v8_snapshot.gypi b/gin/fingerprint/fingerprint_v8_snapshot.gypi new file mode 100644 index 0000000..ede0de3 --- /dev/null +++ b/gin/fingerprint/fingerprint_v8_snapshot.gypi @@ -0,0 +1,47 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is meant to be included into a target to provide a rule that +# fingerprints the v8 snapshot and generates a .cc file which includes this +# fingerprint. +# +# To use this, create a gyp target with the following form: +# { +# 'target_name': 'gin_v8_snapshot_fingerprint', +# 'type': 'none', +# 'variables': { +# 'snapshot_file': 'snapshot blob file to be fingerprinted', +# 'natives_file': 'natives blob file to be fingerprinted', +# 'output_file': 'output .cc file to generate with fingerprints', +# }, +# 'includes': [ '../gin/fingerprint/fingerprint_v8_snapshot.gypi' ], +# }, +# + +{ + 'conditions': [ + ['v8_use_external_startup_data==1', { + 'actions': [ + { + 'action_name': 'Generate V8 snapshot fingerprint', + 'message': 'Generating V8 snapshot fingerprint', + 'inputs': [ + '<(DEPTH)/gin/fingerprint/fingerprint_v8_snapshot.py', + '<(snapshot_file)', + '<(natives_file)', + ], + 'outputs': [ + '<(output_file)', + ], + 'action': [ + 'python', '<(DEPTH)/gin/fingerprint/fingerprint_v8_snapshot.py', + '--snapshot_file=<(snapshot_file)', + '--natives_file=<(natives_file)', + '--output_file=<(output_file)', + ], + } + ], + }], + ], +}
\ No newline at end of file diff --git a/gin/fingerprint/fingerprint_v8_snapshot.py b/gin/fingerprint/fingerprint_v8_snapshot.py new file mode 100755 index 0000000..d1f7092 --- /dev/null +++ b/gin/fingerprint/fingerprint_v8_snapshot.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Fingerprints the V8 snapshot blob files. + +Constructs a SHA256 fingerprint of the V8 natives and snapshot blob files and +creates a .cc file which includes these fingerprint as variables. +""" + +import hashlib +import optparse +import os +import sys + +_HEADER = """// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file was generated by fingerprint_v8_snapshot.py. + +namespace gin { +""" + +_FOOTER = """ +} // namespace gin +""" + + +def FingerprintFile(file_path): + input_file = open(file_path, 'rb') + sha256 = hashlib.sha256() + while True: + block = input_file.read(sha256.block_size) + if not block: + break + sha256.update(block) + return sha256.digest() + + +def WriteFingerprint(output_file, variable_name, fingerprint): + output_file.write('\nextern const unsigned char %s[] = { ' % variable_name) + for byte in fingerprint: + output_file.write(str(ord(byte)) + ', ') + output_file.write('};\n') + + +def WriteOutputFile(natives_fingerprint, + snapshot_fingerprint, + output_file_path): + output_dir_path = os.path.dirname(output_file_path) + if not os.path.exists(output_dir_path): + os.makedirs(output_dir_path) + output_file = open(output_file_path, 'w') + + output_file.write(_HEADER) + WriteFingerprint(output_file, 'g_natives_fingerprint', natives_fingerprint) + output_file.write('\n') + WriteFingerprint(output_file, 'g_snapshot_fingerprint', snapshot_fingerprint) + output_file.write(_FOOTER) + + +def main(): + parser = optparse.OptionParser() + + parser.add_option('--snapshot_file', + help='The input V8 snapshot blob file path.') + parser.add_option('--natives_file', + help='The input V8 natives blob file path.') + parser.add_option('--output_file', + help='The path for the output cc file which will be write.') + + options, _ = parser.parse_args() + + natives_fingerprint = FingerprintFile(options.natives_file) + snapshot_fingerprint = FingerprintFile(options.snapshot_file) + WriteOutputFile( + natives_fingerprint, snapshot_fingerprint, options.output_file) + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/gin/gin.gyp b/gin/gin.gyp index b38dc85..096c120 100644 --- a/gin/gin.gyp +++ b/gin/gin.gyp @@ -5,6 +5,7 @@ { 'variables': { 'chromium_code': 1, + 'gin_gen_path': '<(SHARED_INTERMEDIATE_DIR)/gin/', }, 'targets': [ { @@ -14,7 +15,6 @@ '../base/base.gyp:base', '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', '../v8/tools/gyp/v8.gyp:v8', - ], 'export_dependent_settings': [ '../base/base.gyp:base', @@ -78,6 +78,30 @@ 'wrappable.h', 'wrapper_info.cc', ], + 'conditions': [ + ['v8_use_external_startup_data==1 and OS=="win"', { + 'dependencies': [ + 'gin_v8_snapshot_fingerprint', + '../crypto/crypto.gyp:crypto', + ], + 'sources': [ + '<(gin_gen_path)/v8_snapshot_fingerprint.cc', + ], + 'defines': [ + 'V8_VERIFY_EXTERNAL_STARTUP_DATA', + ] + }], + ], + }, + { + 'target_name': 'gin_v8_snapshot_fingerprint', + 'type': 'none', + 'variables': { + 'snapshot_file': '<(PRODUCT_DIR)/snapshot_blob.bin', + 'natives_file': '<(PRODUCT_DIR)/natives_blob.bin', + 'output_file': '<(gin_gen_path)/v8_snapshot_fingerprint.cc', + }, + 'includes': [ '../gin/fingerprint/fingerprint_v8_snapshot.gypi' ], }, { 'target_name': 'gin_shell', diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc index 2b6d64b..38215b2 100644 --- a/gin/isolate_holder.cc +++ b/gin/isolate_holder.cc @@ -12,6 +12,7 @@ #include "base/message_loop/message_loop.h" #include "base/rand_util.h" #include "base/sys_info.h" +#include "crypto/sha2.h" #include "gin/array_buffer.h" #include "gin/debug_impl.h" #include "gin/function_template.h" @@ -19,8 +20,8 @@ #include "gin/public/v8_platform.h" #include "gin/run_microtasks_observer.h" -#ifdef V8_USE_EXTERNAL_STARTUP_DATA -#ifdef OS_MACOSX +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) +#if defined(OS_MACOSX) #include "base/mac/foundation_util.h" #endif // OS_MACOSX #include "base/path_service.h" @@ -40,7 +41,7 @@ bool GenerateEntropy(unsigned char* buffer, size_t amount) { base::MemoryMappedFile* g_mapped_natives = NULL; base::MemoryMappedFile* g_mapped_snapshot = NULL; -#ifdef V8_USE_EXTERNAL_STARTUP_DATA +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) bool MapV8Files(base::FilePath* natives_path, base::FilePath* snapshot_path, int natives_fd = -1, int snapshot_fd = -1) { int flags = base::File::FLAG_OPEN | base::File::FLAG_READ; @@ -72,21 +73,39 @@ bool MapV8Files(base::FilePath* natives_path, base::FilePath* snapshot_path, return true; } +#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) +bool VerifyV8SnapshotFile(base::MemoryMappedFile* snapshot_file, + const unsigned char* fingerprint) { + unsigned char output[crypto::kSHA256Length]; + crypto::SHA256HashString( + base::StringPiece(reinterpret_cast<const char*>(snapshot_file->data()), + snapshot_file->length()), + output, sizeof(output)); + return !memcmp(fingerprint, output, sizeof(output)); +} +#endif // V8_VERIFY_EXTERNAL_STARTUP_DATA + #if !defined(OS_MACOSX) const int v8_snapshot_dir = #if defined(OS_ANDROID) base::DIR_ANDROID_APP_DATA; #elif defined(OS_POSIX) base::DIR_EXE; -#endif // defined(OS_ANDROID) -#endif // !defined(OS_MACOSX) +#endif // OS_ANDROID +#endif // !OS_MACOSX #endif // V8_USE_EXTERNAL_STARTUP_DATA } // namespace +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) + +#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) +// Defined in gen/gin/v8_snapshot_fingerprint.cc +extern const unsigned char g_natives_fingerprint[]; +extern const unsigned char g_snapshot_fingerprint[]; +#endif // V8_VERIFY_EXTERNAL_STARTUP_DATA -#ifdef V8_USE_EXTERNAL_STARTUP_DATA // static bool IsolateHolder::LoadV8Snapshot() { if (g_mapped_natives && g_mapped_snapshot) @@ -108,7 +127,15 @@ bool IsolateHolder::LoadV8Snapshot() { DCHECK(!snapshot_path.empty()); #endif // !defined(OS_MACOSX) - return MapV8Files(&natives_path, &snapshot_path); + if (!MapV8Files(&natives_path, &snapshot_path)) + return false; + +#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) + return VerifyV8SnapshotFile(g_mapped_natives, g_natives_fingerprint) && + VerifyV8SnapshotFile(g_mapped_snapshot, g_snapshot_fingerprint); +#else + return true; +#endif // V8_VERIFY_EXTERNAL_STARTUP_DATA } //static @@ -193,7 +220,7 @@ void IsolateHolder::Initialize(ScriptMode mode, v8::V8::SetFlagsFromString(v8_flags, sizeof(v8_flags) - 1); } v8::V8::SetEntropySource(&GenerateEntropy); -#ifdef V8_USE_EXTERNAL_STARTUP_DATA +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) v8::StartupData natives; natives.data = reinterpret_cast<const char*>(g_mapped_natives->data()); natives.raw_size = static_cast<int>(g_mapped_natives->length()); diff --git a/gin/public/isolate_holder.h b/gin/public/isolate_holder.h index b12734c..64fc952 100644 --- a/gin/public/isolate_holder.h +++ b/gin/public/isolate_holder.h @@ -51,7 +51,7 @@ class GIN_EXPORT IsolateHolder { // thread. void RemoveRunMicrotasksObserver(); -#ifdef V8_USE_EXTERNAL_STARTUP_DATA +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) static bool LoadV8SnapshotFD(int natives_fd, int snapshot_fd); static bool LoadV8Snapshot(); #endif // V8_USE_EXTERNAL_STARTUP_DATA |