summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/app/content_main_runner.cc8
-rw-r--r--gin/BUILD.gn36
-rw-r--r--gin/DEPS1
-rw-r--r--gin/fingerprint/fingerprint_v8_snapshot.gypi47
-rwxr-xr-xgin/fingerprint/fingerprint_v8_snapshot.py86
-rw-r--r--gin/gin.gyp26
-rw-r--r--gin/isolate_holder.cc43
-rw-r--r--gin/public/isolate_holder.h2
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") {
diff --git a/gin/DEPS b/gin/DEPS
index 4e3f30a..d4cc2ba 100644
--- a/gin/DEPS
+++ b/gin/DEPS
@@ -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