Commit 496fe9b7 authored by Ken Rockot's avatar Ken Rockot Committed by Commit Bot

Mojo: Scramble message IDs at build time

Applies mojom bindings-generation-time message ID
scrambling to all mojom targets by default. Changes the
generator's salt flag to take a filename, and uses some
GN and LASTCHANGE magic to ensure that the salt file is
updated on each build revision.

This behavior can be disabled in specific mojom GN targets
by setting |scramble_message_ids| to |false|, which is done
here for ARC mojoms to avoid compatibility issues between
Chrome and the ARC container.

BUG=673417

Change-Id: I4263a4b90400a09fed8286b362108f13376b88c5
Reviewed-on: https://chromium-review.googlesource.com/685457
Commit-Queue: Ken Rockot <rockot@chromium.org>
Reviewed-by: default avatarLuis Hector Chavez <lhchavez@chromium.org>
Reviewed-by: default avatarYuzhu Shen <yzshen@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#505219}
parent 7e4917f6
......@@ -201,6 +201,10 @@ mojom("arc_bindings") {
"//mojo/common:common_custom_types",
"//ui/gfx/geometry/mojo",
]
# ARC is built outside of the Chromium source tree, so we need to have stable
# message IDs for the generated bindings.
scramble_message_ids = false
}
static_library("arc_test_support") {
......
......@@ -14,4 +14,9 @@ mojom("interfaces") {
deps = [
"//mojo/common:common_custom_types",
]
# USB Mojom interfaces are exposed publicly to layout tests which use
# prepackaged redistributable JS bindings. It is therefore not desirable to
# scramble these messages.
scramble_message_ids = false
}
......@@ -73,6 +73,10 @@ mojom("test_interfaces") {
use_once_callback = false
support_lazy_serialization = true
# Validation tests require precise message content matching, so we avoid
# scrambling message IDs for test interfaces.
scramble_message_ids = false
}
component("test_export_component") {
......@@ -212,6 +216,10 @@ mojom("test_associated_interfaces") {
# TODO(crbug.com/714018): Convert the implementation to use OnceCallback.
use_once_callback = false
# Validation tests require precise message content matching, so we avoid
# scrambling message IDs for test interfaces.
scramble_message_ids = false
}
mojom("versioning_test_service_interfaces") {
......
......@@ -74,4 +74,28 @@ action("precompile_templates") {
"-o",
rebase_path(target_gen_dir, root_build_dir),
]
deps = [
":generate_message_id_salt($default_toolchain)",
]
}
# NOTE: We need to ensure that there is only ONE message salt generation step
# run for the whole build, regardless of toolchain. Otherwise each toolchain
# will end up using its own isolated salt and message IDs will not match across
# runtime boundaries (e.g. NaCl code talking to non-NaCl code over mojom).
if (current_toolchain == default_toolchain) {
action("generate_message_id_salt") {
script = "//mojo/public/tools/bindings/generate_message_id_salt.py"
# Force update on any release version change.
inputs = [
"//chrome/VERSION",
]
outputs = [
"$target_gen_dir/mojom-message-id-salt",
]
args =
[ rebase_path("$target_gen_dir/mojom-message-id-salt", root_build_dir) ]
}
}
#!/usr/bin/env python
# Copyright 2017 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.
import datetime
import sys
# Generates a file whose contents are based on the current datetime. This file
# may be used as a build-wide dependency and input into the mojom bindings
# generator's --scrambled_message_id_salt flag to scramble message IDs in a
# unique but globally consistent manner for each build.
def main(output_file):
with open(output_file, 'w') as f:
f.write(str(datetime.datetime.now()))
if __name__ == '__main__':
if len(sys.argv) < 2:
print "Missing output filename."
sys.exit(1)
sys.exit(main(sys.argv[1]))
......@@ -16,6 +16,13 @@ declare_args() {
mojom_generator_root = "//mojo/public/tools/bindings"
mojom_generator_script = "$mojom_generator_root/mojom_bindings_generator.py"
# See //mojo/public/tools/bindings:generate_message_id_salt
mojom_message_id_salt_filename = get_label_info(
"//mojo/public/tools/bindings:generate_message_id_salt($default_toolchain)",
"target_gen_dir") +
"/mojom-message-id-salt"
mojom_generator_sources = [
"$mojom_generator_root/generators/mojom_cpp_generator.py",
"$mojom_generator_root/generators/mojom_js_generator.py",
......@@ -34,6 +41,7 @@ mojom_generator_sources = [
"$mojom_generator_root/pylib/mojom/parse/lexer.py",
"$mojom_generator_root/pylib/mojom/parse/parser.py",
"$mojom_generator_script",
"$mojom_message_id_salt_filename",
]
generate_export_header_script =
......@@ -184,6 +192,10 @@ if (enable_mojom_typemapping) {
# be serialized and deserialized using a legacy IPC::ParamTraits
# specialization.
#
# scramble_message_ids (optional)
# If set to |true| (the default), generated mojom interfaces will use
# scrambled ordinal identifiers in encoded messages.
#
# component_output_prefix (optional)
# The prefix to use for the output_name of any component library emitted
# for generated C++ bindings. If this is omitted, C++ bindings targets are
......@@ -323,6 +335,13 @@ template("mojom") {
rebase_path("$root_gen_dir/mojo/public/tools/bindings", root_build_dir),
]
if (!defined(invoker.scramble_message_ids) || invoker.scramble_message_ids) {
common_generator_args += [
"--scrambled_message_id_salt",
rebase_path("$mojom_message_id_salt_filename", root_build_dir),
]
}
if (!defined(invoker.allow_native_structs) || invoker.allow_native_structs) {
common_generator_args += [ "--allow_native_structs" ]
}
......@@ -388,6 +407,7 @@ template("mojom") {
inputs = mojom_generator_sources
sources = invoker.sources
deps = [
"//mojo/public/tools/bindings:generate_message_id_salt($default_toolchain)",
"//mojo/public/tools/bindings:precompile_templates",
]
outputs = generator_shared_cpp_outputs
......@@ -608,6 +628,7 @@ template("mojom") {
sources = invoker.sources
deps = [
":$type_mappings_target_name",
"//mojo/public/tools/bindings:generate_message_id_salt($default_toolchain)",
"//mojo/public/tools/bindings:precompile_templates",
]
outputs = generator_cpp_outputs + generator_java_outputs
......@@ -922,6 +943,7 @@ template("mojom") {
sources += invoker.sources
}
deps = [
"//mojo/public/tools/bindings:generate_message_id_salt($default_toolchain)",
"//mojo/public/tools/bindings:precompile_templates",
]
outputs = generator_js_outputs
......
......@@ -119,7 +119,7 @@ def ScrambleMethodOrdinals(interfaces, salt):
# to guess the results without the secret salt, in order to make it
# harder for a compromised process to send fake Mojo messages.
sha256 = hashlib.sha256(salt)
sha256.update(interface.name)
sha256.update(interface.mojom_name)
sha256.update(str(i))
# Take the first 4 bytes as a little-endian uint32.
ordinal = struct.unpack('<L', sha256.digest()[:4])[0]
......@@ -131,7 +131,7 @@ def ScrambleMethodOrdinals(interfaces, salt):
method.ordinal = ordinal
method.ordinal_comment = (
'The %s value is based on sha256(salt + "%s%d").' %
(ordinal, interface.name, i))
(ordinal, interface.mojom_name, i))
break
......@@ -194,7 +194,9 @@ class MojomProcessor(object):
module = translate.OrderedModule(tree, module_path, imports)
if args.scrambled_message_id_salt:
ScrambleMethodOrdinals(module.interfaces, args.scrambled_message_id_salt)
with open(args.scrambled_message_id_salt, 'r') as f:
salt = f.read()
ScrambleMethodOrdinals(module.interfaces, salt)
if self._should_generate(rel_filename.path):
AddComputedData(module)
......@@ -363,7 +365,8 @@ def main():
help="The target name to use in the depfile.")
generate_parser.add_argument(
"--scrambled_message_id_salt",
help="If non-empty, the salt for generating scrambled message IDs.")
help="If non-empty, the name of a file containing a salt for generating"
"scrambled message IDs.")
generate_parser.add_argument(
"--support_lazy_serialization",
help="If set, generated bindings will serialize lazily when possible.",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment