fuzzing: introduce automated IPC fuzzing
This CL introduces a fuzzer that automatically detects renderer process exposed IPC interfaces and fuzzes them. The design of this fuzzer has been described at https://docs.google.com/document/d/1Y5yy8YTJRLPQUPHzPO-KhmT-gZoBkLjWp2eRaJbBpq4/edit?usp=sharing. Because GN does not support dynamic dependencies, this patch needs to introduce a gni file at `chrome/browser_exposed_mojom_targets.gni` which lists all the targets of browser exposed mojom interfaces on Linux. Please, check this doc to read about pros and cons about the different considered solutions: https://docs.google.com/document/d/1BSgrxtXVKGEtVU5KoKZbvZfQOxIZb2fqYcAX4FXYw8E. Thanks to this automated IPC fuzzer, any new browser-exposed IPC endpoint will be fuzzed as soon as it gets in the codebase. Doing this, we aim at detecting potential issues as soon as possible. Bug: 40282115 Cq-Include-Trybots: luci.chromium.try:linux-centipede-asan-rel Change-Id: I1f097b871d53c4f2a34c62c43bbede1fd23d760a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5490095 Reviewed-by: Adrian Taylor <adetaylor@chromium.org> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Commit-Queue: Paul Semel <paulsemel@chromium.org> Cr-Commit-Position: refs/heads/main@{#1310532}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
11a700e804
commit
90ef9055a5
345
chrome/browser_exposed_mojom_targets.gni
Normal file
345
chrome/browser_exposed_mojom_targets.gni
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
# Copyright 2024 The Chromium Authors
|
||||||
|
# Use of this source code is governed by a BSD-style license that can be
|
||||||
|
# found in the LICENSE file.
|
||||||
|
#
|
||||||
|
|
||||||
|
# This file represents global knowledge about all the mojom targets building
|
||||||
|
# browser-to-renderer exposed mojom interfaces. Developers are responsible for
|
||||||
|
# maintaining this file to match addition and removal of newly exposed targets.
|
||||||
|
# This is part of our automated fuzzing of the browser/renderer interface that
|
||||||
|
# lives at `//chrome/test/fuzzing/renderer_fuzzing/ipc_fuzzing`.
|
||||||
|
# As for now, we are only listing those targets for interfaces exposed on
|
||||||
|
# Linux.
|
||||||
|
|
||||||
|
browser_exposed_mojom_targets = [
|
||||||
|
"//cc/mojom:layer_type",
|
||||||
|
"//cc/mojom:mojom",
|
||||||
|
"//chrome/browser/cart:mojo_bindings",
|
||||||
|
"//chrome/browser/companion/core/mojom:mojo_bindings",
|
||||||
|
"//chrome/browser/lens/core/mojom:mojo_bindings",
|
||||||
|
"//chrome/browser/media:mojo_bindings",
|
||||||
|
"//chrome/browser/new_tab_page/modules/feed:mojo_bindings",
|
||||||
|
"//chrome/browser/new_tab_page/modules/file_suggestion:mojo_bindings",
|
||||||
|
"//chrome/browser/new_tab_page/modules/history_clusters:mojo_bindings",
|
||||||
|
"//chrome/browser/new_tab_page/modules/history_clusters/cart:mojo_bindings",
|
||||||
|
"//chrome/browser/new_tab_page/modules/history_clusters/discount:mojo_bindings",
|
||||||
|
"//chrome/browser/new_tab_page/modules/photos:mojo_bindings",
|
||||||
|
"//chrome/browser/new_tab_page/modules/recipes:mojo_bindings",
|
||||||
|
"//chrome/browser/new_tab_page/modules/safe_browsing:mojo_bindings",
|
||||||
|
"//chrome/browser/new_tab_page/modules/v2/calendar:mojo_bindings",
|
||||||
|
"//chrome/browser/new_tab_page/modules/v2/history_clusters:mojo_bindings",
|
||||||
|
"//chrome/browser/new_tab_page/modules/v2/most_relevant_tab_resumption:mojo_bindings",
|
||||||
|
"//chrome/browser/new_tab_page/modules/v2/tab_resumption:mojo_bindings",
|
||||||
|
"//chrome/browser/resource_coordinator:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/access_code_cast:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/app_home:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/app_service_internals:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/bluetooth_internals:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/connectors_internals:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/data_sharing_internals:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/discards:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/downloads:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/hats:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/internals/user_education:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/location_internals:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/new_tab_page_third_party:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/new_tab_page:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/new_tab_page/foo:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/omnibox:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/on_device_internals:mojom",
|
||||||
|
"//chrome/browser/ui/webui/privacy_sandbox:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/reset_password:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/search_engine_choice:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/segmentation_internals:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/side_panel/bookmarks:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/side_panel/customize_chrome:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/side_panel/performance_controls:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/side_panel/reading_list:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/suggest_internals:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/tab_search:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/tab_strip:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/tabs:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/usb_internals:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/web_app_internals:mojo_bindings",
|
||||||
|
"//chrome/browser/ui/webui/whats_new:mojo_bindings",
|
||||||
|
"//chrome/browser/web_applications/mojom:mojom_web_apps_enum",
|
||||||
|
"//chrome/common:available_offline_content_mojom",
|
||||||
|
"//chrome/common:mojo_bindings",
|
||||||
|
"//chrome/common:offline_page_auto_fetcher_mojom",
|
||||||
|
"//chrome/common:supervised_user_commands_mojom",
|
||||||
|
"//chrome/common/accessibility:mojo_bindings",
|
||||||
|
"//chrome/common/cart:mojo_bindings",
|
||||||
|
"//chrome/common/companion:mojo_bindings",
|
||||||
|
"//chrome/common/compose:mojo_bindings",
|
||||||
|
"//chrome/common/importer:interfaces",
|
||||||
|
"//chrome/common/search:mojo_bindings",
|
||||||
|
"//chrome/services/file_util/public/mojom:mojom",
|
||||||
|
"//chrome/services/media_gallery_util/public/mojom:mojom",
|
||||||
|
"//chrome/services/on_device_translation/public/mojom:mojom",
|
||||||
|
"//chrome/services/printing/public/mojom:mojom",
|
||||||
|
"//chrome/services/removable_storage_writer/public/mojom:mojom",
|
||||||
|
"//components/attribution_reporting:mojom",
|
||||||
|
"//components/attribution_reporting:registration_header_error_mojom",
|
||||||
|
"//components/attribution_reporting:registration_mojom",
|
||||||
|
"//components/attribution_reporting:source_type_mojom",
|
||||||
|
"//components/autofill/content/common/mojom:mojom",
|
||||||
|
"//components/autofill/core/common/mojom:mojo_types",
|
||||||
|
"//components/browsing_topics/mojom:mojo_bindings",
|
||||||
|
"//components/commerce/core/internals/mojom:mojo_bindings",
|
||||||
|
"//components/commerce/core/mojom:mojo_bindings",
|
||||||
|
"//components/compose/core/browser:mojo_bindings",
|
||||||
|
"//components/content_capture/common:mojo_interfaces",
|
||||||
|
"//components/content_capture/common:mojo_types",
|
||||||
|
"//components/content_settings/common:mojom",
|
||||||
|
"//components/content_settings/core/common:content_settings_enums",
|
||||||
|
"//components/content_settings/core/common:content_settings_types",
|
||||||
|
"//components/content_settings/core/common:mojo_bindings",
|
||||||
|
"//components/continuous_search/common/public/mojom:mojom",
|
||||||
|
"//components/device_signals/core/common/mojom:mojom",
|
||||||
|
"//components/digital_goods/mojom:mojom",
|
||||||
|
"//components/discardable_memory/public/mojom:mojom",
|
||||||
|
"//components/dom_distiller/content/common/mojom:mojom",
|
||||||
|
"//components/dom_distiller/core/mojom:mojom",
|
||||||
|
"//components/download/public/common:interfaces",
|
||||||
|
"//components/facilitated_payments/core/mojom:facilitated_payments_agent_mojom",
|
||||||
|
"//components/facilitated_payments/core/mojom:pix_code_validator_mojom",
|
||||||
|
"//components/feed/mojom:mojo_bindings",
|
||||||
|
"//components/global_media_controls/public/mojom:device_service",
|
||||||
|
"//components/guest_view/common:mojom",
|
||||||
|
"//components/heap_profiling/in_process:mojom",
|
||||||
|
"//components/history_clusters/history_clusters_internals/webui:mojo_bindings",
|
||||||
|
"//components/history_clusters/public/mojom:mojo_bindings",
|
||||||
|
"//components/history/core/browser/mojom:mojo_bindings",
|
||||||
|
"//components/lens:lens_mojo",
|
||||||
|
"//components/media_router/common/mojom:debugger",
|
||||||
|
"//components/media_router/common/mojom:logger",
|
||||||
|
"//components/media_router/common/mojom:media_controller",
|
||||||
|
"//components/media_router/common/mojom:media_route_provider_id",
|
||||||
|
"//components/media_router/common/mojom:media_router",
|
||||||
|
"//components/media_router/common/mojom:route_request_result_code",
|
||||||
|
"//components/metrics/public/mojom:call_stack_mojo_bindings",
|
||||||
|
"//components/metrics/public/mojom:histogram_fetcher_mojo_bindings",
|
||||||
|
"//components/metrics/public/mojom:single_sample_metrics_mojo_bindings",
|
||||||
|
"//components/metrics/structured/mojom:mojom",
|
||||||
|
"//components/mirroring/mojom:common",
|
||||||
|
"//components/mirroring/mojom:service",
|
||||||
|
"//components/ml/mojom:mojom",
|
||||||
|
"//components/ml/webnn:features",
|
||||||
|
"//components/network_hints/common:mojo_bindings",
|
||||||
|
"//components/no_state_prefetch/common:mojo_bindings",
|
||||||
|
"//components/omnibox/browser:mojo_bindings",
|
||||||
|
"//components/optimization_guide/content/mojom:mojo_interfaces",
|
||||||
|
"//components/optimization_guide/core:interfaces",
|
||||||
|
"//components/optimization_guide/optimization_guide_internals/webui:mojo_bindings",
|
||||||
|
"//components/os_crypt/async/common:algorithm_mojom",
|
||||||
|
"//components/os_crypt/async/common:common_mojom",
|
||||||
|
"//components/page_image_service/mojom:mojo_bindings",
|
||||||
|
"//components/page_load_metrics/common:page_load_metrics_mojom",
|
||||||
|
"//components/paint_preview/common/mojom:mojom",
|
||||||
|
"//components/password_manager/services/csv_password/public/mojom:mojom",
|
||||||
|
"//components/payments/mojom:mojom",
|
||||||
|
"//components/performance_manager/public/mojom:mojom",
|
||||||
|
"//components/printing/common:mojo_interfaces",
|
||||||
|
"//components/safe_browsing/content/common:interfaces",
|
||||||
|
"//components/safe_browsing/core/common:interfaces",
|
||||||
|
"//components/schema_org/common:improved_mojom",
|
||||||
|
"//components/schema_org/common:mojom",
|
||||||
|
"//components/security_interstitials/core/common/mojom:mojom",
|
||||||
|
"//components/services/filesystem/public/mojom:mojom",
|
||||||
|
"//components/services/font/public/mojom:mojom",
|
||||||
|
"//components/services/heap_profiling/public/mojom:mojom",
|
||||||
|
"//components/services/language_detection/public/mojom:mojom",
|
||||||
|
"//components/services/paint_preview_compositor/public/mojom:mojom",
|
||||||
|
"//components/services/patch/public/mojom:mojom",
|
||||||
|
"//components/services/print_compositor/public/mojom:mojom",
|
||||||
|
"//components/services/quarantine/public/mojom:mojom",
|
||||||
|
"//components/services/storage/privileged/mojom:mojom_bucket",
|
||||||
|
"//components/services/storage/privileged/mojom:mojom",
|
||||||
|
"//components/services/storage/public/mojom:mojom",
|
||||||
|
"//components/services/storage/public/mojom/buckets:buckets",
|
||||||
|
"//components/services/storage/public/mojom/filesystem:filesystem",
|
||||||
|
"//components/services/unzip/public/mojom:mojom",
|
||||||
|
"//components/site_engagement/core/mojom:mojo_bindings",
|
||||||
|
"//components/spellcheck/common:interfaces",
|
||||||
|
"//components/subresource_filter/content/mojom:mojom",
|
||||||
|
"//components/subresource_filter/core/mojom:mojom",
|
||||||
|
"//components/tab_groups/public/mojom:mojo_bindings",
|
||||||
|
"//components/translate/content/common:common",
|
||||||
|
"//components/variations:variations_mojom",
|
||||||
|
"//components/visitedlink/common:interfaces",
|
||||||
|
"//components/viz/service/debugger/mojom:mojom",
|
||||||
|
"//components/web_cache/public/mojom:mojom",
|
||||||
|
"//components/web_package/mojom:mojom",
|
||||||
|
"//components/webapps/common:mojo_bindings",
|
||||||
|
"//components/webapps/services/web_app_origin_association/public/mojom:mojom",
|
||||||
|
"//content/browser/attribution_reporting:internals_mojo_bindings",
|
||||||
|
"//content/browser/attribution_reporting:mojo_bindings",
|
||||||
|
"//content/browser/attribution_reporting:registration_result_mojom",
|
||||||
|
"//content/browser/indexed_db:internals_mojo_bindings",
|
||||||
|
"//content/browser/private_aggregation:mojo_bindings",
|
||||||
|
"//content/browser/process_internals:mojo_bindings",
|
||||||
|
"//content/browser/tracing/trace_report:mojo_bindings",
|
||||||
|
"//content/browser/xr/webxr_internals/mojom:mojo_bindings",
|
||||||
|
"//content/common:mojo_bindings",
|
||||||
|
"//content/public/common:interfaces",
|
||||||
|
"//content/public/common:renderer_type",
|
||||||
|
"//device/bluetooth/public/mojom:deprecated_experimental_interfaces",
|
||||||
|
"//device/bluetooth/public/mojom:mojom",
|
||||||
|
"//device/gamepad/public/mojom:mojom",
|
||||||
|
"//device/vr/public/mojom:isolated_xr_service",
|
||||||
|
"//device/vr/public/mojom:test_mojom",
|
||||||
|
"//device/vr/public/mojom:vr_service",
|
||||||
|
"//device/vr/public/mojom:xr_common",
|
||||||
|
"//extensions/common:mojom",
|
||||||
|
"//extensions/common/api:mojom",
|
||||||
|
"//gpu/ipc/common:gmb_interface",
|
||||||
|
"//gpu/ipc/common:gpu_channel_mojom",
|
||||||
|
"//gpu/ipc/common:gpu_preferences_interface",
|
||||||
|
"//gpu/ipc/common:interfaces",
|
||||||
|
"//gpu/ipc/common:surface_handle",
|
||||||
|
"//gpu/ipc/common:vulkan_interface",
|
||||||
|
"//ipc:mojom_constants",
|
||||||
|
"//ipc:mojom",
|
||||||
|
"//media/capture/mojom:image_capture",
|
||||||
|
"//media/capture/mojom:video_capture_buffer",
|
||||||
|
"//media/capture/mojom:video_capture_types",
|
||||||
|
"//media/capture/mojom:video_capture",
|
||||||
|
"//media/capture/mojom:video_effects_manager",
|
||||||
|
"//media/learning/mojo/public/mojom:mojom",
|
||||||
|
"//media/midi:mojo",
|
||||||
|
"//media/mojo/mojom:audio_data",
|
||||||
|
"//media/mojo/mojom:encryption_pattern",
|
||||||
|
"//media/mojo/mojom:mojom",
|
||||||
|
"//media/mojo/mojom:remoting_common",
|
||||||
|
"//media/mojo/mojom:remoting",
|
||||||
|
"//media/mojo/mojom:speech_recognition_audio_forwarder",
|
||||||
|
"//media/mojo/mojom:speech_recognition",
|
||||||
|
"//media/mojo/mojom:web_speech_recognition",
|
||||||
|
"//media/mojo/mojom/stable:native_pixmap_handle",
|
||||||
|
"//media/mojo/mojom/stable:stable_video_decoder",
|
||||||
|
"//mojo/public/interfaces/bindings:bindings",
|
||||||
|
"//mojo/public/mojom/base:base",
|
||||||
|
"//mojo/public/mojom/base:protobuf_support",
|
||||||
|
"//pdf/mojom:mojom",
|
||||||
|
"//printing/backend/mojom:mojom",
|
||||||
|
"//printing/mojom:mojom",
|
||||||
|
"//printing/mojom:printing_context",
|
||||||
|
"//sandbox/policy/mojom:mojom",
|
||||||
|
"//services/accessibility/public/mojom:automation_client",
|
||||||
|
"//services/accessibility/public/mojom:automation",
|
||||||
|
"//services/accessibility/public/mojom:mojom",
|
||||||
|
"//services/audio/public/mojom:mojom",
|
||||||
|
"//services/cert_verifier/public/mojom:mojom",
|
||||||
|
"//services/data_decoder/public/mojom:mojom_xml_parser",
|
||||||
|
"//services/data_decoder/public/mojom:mojom",
|
||||||
|
"//services/device/public/mojom:device_service",
|
||||||
|
"//services/device/public/mojom:generic_sensor",
|
||||||
|
"//services/device/public/mojom:geolocation_internals",
|
||||||
|
"//services/device/public/mojom:geoposition",
|
||||||
|
"//services/device/public/mojom:mojom",
|
||||||
|
"//services/device/public/mojom:usb_test",
|
||||||
|
"//services/device/public/mojom:usb",
|
||||||
|
"//services/image_annotation/public/mojom:mojom",
|
||||||
|
"//services/media_session/public/mojom:mojom",
|
||||||
|
"//services/metrics/public/mojom:mojom",
|
||||||
|
"//services/network/public/mojom:cookies_mojom",
|
||||||
|
"//services/network/public/mojom:mojom_attribution",
|
||||||
|
"//services/network/public/mojom:mojom_first_party_sets",
|
||||||
|
"//services/network/public/mojom:mojom_host_resolver",
|
||||||
|
"//services/network/public/mojom:mojom_ip_address",
|
||||||
|
"//services/network/public/mojom:mojom_network_anonymization_key",
|
||||||
|
"//services/network/public/mojom:mojom_network_isolation_key",
|
||||||
|
"//services/network/public/mojom:mojom_network_param",
|
||||||
|
"//services/network/public/mojom:mojom_proxy_config",
|
||||||
|
"//services/network/public/mojom:mojom_schemeful_site",
|
||||||
|
"//services/network/public/mojom:mojom_shared_dictionary",
|
||||||
|
"//services/network/public/mojom:mojom_structured_headers",
|
||||||
|
"//services/network/public/mojom:mojom",
|
||||||
|
"//services/network/public/mojom:url_loader_base",
|
||||||
|
"//services/network/public/mojom:websocket_mojom",
|
||||||
|
"//services/on_device_model/public/mojom:mojom",
|
||||||
|
"//services/passage_embeddings/public/mojom:mojom",
|
||||||
|
"//services/preferences/public/mojom:mojom",
|
||||||
|
"//services/proxy_resolver/public/mojom:mojom",
|
||||||
|
"//services/resource_coordinator/public/mojom:mojom",
|
||||||
|
"//services/screen_ai/public/mojom:factory",
|
||||||
|
"//services/screen_ai/public/mojom:mojom",
|
||||||
|
"//services/service_manager/public/mojom:constants",
|
||||||
|
"//services/service_manager/public/mojom:mojom",
|
||||||
|
"//services/shape_detection/public/mojom:mojom",
|
||||||
|
"//services/tracing/public/mojom:mojom",
|
||||||
|
"//services/video_capture/public/mojom:constants",
|
||||||
|
"//services/video_capture/public/mojom:mojom",
|
||||||
|
"//services/video_effects/public/mojom:mojom",
|
||||||
|
"//services/viz/privileged/mojom:mojom",
|
||||||
|
"//services/viz/privileged/mojom/compositing:compositing",
|
||||||
|
"//services/viz/privileged/mojom/gl:gl",
|
||||||
|
"//services/viz/public/mojom:mojom",
|
||||||
|
"//services/viz/public/mojom:shared_image_format",
|
||||||
|
"//services/viz/public/mojom:singleplanar_format",
|
||||||
|
"//services/webnn/public/mojom:mojom",
|
||||||
|
"//skia/public/mojom:mojom",
|
||||||
|
"//storage/browser/quota:mojo_bindings",
|
||||||
|
"//third_party/blink/public/mojom:android_mojo_bindings",
|
||||||
|
"//third_party/blink/public/mojom:authenticator_test_mojo_bindings",
|
||||||
|
"//third_party/blink/public/mojom:color_scheme_mojo_bindings",
|
||||||
|
"//third_party/blink/public/mojom:embedded_frame_sink_mojo_bindings",
|
||||||
|
"//third_party/blink/public/mojom:memory_usage_monitor_linux_mojo_bindings",
|
||||||
|
"//third_party/blink/public/mojom:mojom_core",
|
||||||
|
"//third_party/blink/public/mojom:mojom_mhtml_load_result",
|
||||||
|
"//third_party/blink/public/mojom:mojom_modules",
|
||||||
|
"//third_party/blink/public/mojom:mojom_platform",
|
||||||
|
"//third_party/blink/public/mojom:script_type_mojo_bindings",
|
||||||
|
"//third_party/blink/public/mojom:web_bluetooth_mojo_bindings",
|
||||||
|
"//third_party/blink/public/mojom:web_feature_mojo_bindings",
|
||||||
|
"//third_party/blink/public/mojom/gpu:gpu",
|
||||||
|
"//third_party/blink/public/mojom/origin_trial_feature:origin_trial_feature",
|
||||||
|
"//third_party/blink/public/mojom/origin_trial_state:origin_trial_state",
|
||||||
|
"//third_party/blink/public/mojom/private_network_device:private_network_device",
|
||||||
|
"//third_party/blink/public/mojom/quota:quota",
|
||||||
|
"//third_party/blink/public/mojom/runtime_feature_state:runtime_feature_state",
|
||||||
|
"//third_party/blink/public/mojom/service_worker:storage",
|
||||||
|
"//third_party/blink/public/mojom/storage_key:storage_key",
|
||||||
|
"//third_party/blink/public/mojom/tokens:tokens",
|
||||||
|
"//third_party/blink/public/mojom/usb:usb",
|
||||||
|
"//ui/accessibility:ax_constants_mojo",
|
||||||
|
"//ui/accessibility:ax_enums_mojo",
|
||||||
|
"//ui/accessibility:ax_features_mojo",
|
||||||
|
"//ui/accessibility/mojom:mojom",
|
||||||
|
"//ui/base/cursor/mojom:cursor_type",
|
||||||
|
"//ui/base/cursor/mojom:mojom",
|
||||||
|
"//ui/base/dragdrop/mojom:mojom",
|
||||||
|
"//ui/base/ime/mojom:mojom",
|
||||||
|
"//ui/base/mojom:mojom",
|
||||||
|
"//ui/color:mojom",
|
||||||
|
"//ui/display/mojom:mojom",
|
||||||
|
"//ui/events/mojom:event_latency_metadata_mojom",
|
||||||
|
"//ui/events/mojom:mojom",
|
||||||
|
"//ui/gfx/geometry/mojom:mojom",
|
||||||
|
"//ui/gfx/image/mojom:mojom",
|
||||||
|
"//ui/gfx/mojom:hdr_metadata",
|
||||||
|
"//ui/gfx/mojom:mojom",
|
||||||
|
"//ui/gfx/mojom:native_handle_types",
|
||||||
|
"//ui/gfx/range/mojom:mojom",
|
||||||
|
"//ui/gl/mojom:mojom",
|
||||||
|
"//ui/latency/mojom:mojom",
|
||||||
|
"//ui/ozone/platform/wayland/mojom:mojom",
|
||||||
|
"//ui/ozone/public/mojom:gesture_properties_service",
|
||||||
|
"//ui/webui/resources/cr_components/app_management:mojo_bindings",
|
||||||
|
"//ui/webui/resources/cr_components/certificate_manager:mojom",
|
||||||
|
"//ui/webui/resources/cr_components/color_change_listener:mojom",
|
||||||
|
"//ui/webui/resources/cr_components/commerce:mojo_bindings",
|
||||||
|
"//ui/webui/resources/cr_components/customize_color_scheme_mode:mojom",
|
||||||
|
"//ui/webui/resources/cr_components/customize_themes:mojom",
|
||||||
|
"//ui/webui/resources/cr_components/help_bubble:mojo_bindings",
|
||||||
|
"//ui/webui/resources/cr_components/history_clusters:mojo_bindings",
|
||||||
|
"//ui/webui/resources/cr_components/history_embeddings:mojo_bindings",
|
||||||
|
"//ui/webui/resources/cr_components/most_visited:mojom",
|
||||||
|
"//ui/webui/resources/cr_components/searchbox:mojo_bindings",
|
||||||
|
"//ui/webui/resources/cr_components/theme_color_picker:mojom",
|
||||||
|
"//ui/webui/resources/js/browser_command:mojo_bindings",
|
||||||
|
"//ui/webui/resources/js/metrics_reporter:mojo_bindings",
|
||||||
|
"//url/mojom:url_mojom_gurl",
|
||||||
|
"//url/mojom:url_mojom_origin",
|
||||||
|
"//url/mojom:url_mojom_scheme_host_port",
|
||||||
|
]
|
@ -2,15 +2,22 @@
|
|||||||
# Use of this source code is governed by a BSD-style license that can be
|
# Use of this source code is governed by a BSD-style license that can be
|
||||||
# found in the LICENSE file.
|
# found in the LICENSE file.
|
||||||
|
|
||||||
|
import("//chrome/browser_exposed_mojom_targets.gni")
|
||||||
import("//chrome/test/fuzzing/in_process_fuzzer.gni")
|
import("//chrome/test/fuzzing/in_process_fuzzer.gni")
|
||||||
import("//chrome/test/fuzzing/renderer_fuzzing/in_process_renderer_fuzzing.gni")
|
import("//chrome/test/fuzzing/renderer_fuzzing/in_process_renderer_fuzzing.gni")
|
||||||
import(
|
|
||||||
"//chrome/test/fuzzing/renderer_fuzzing/ipc_fuzzing/mojom_interfaces.gni")
|
|
||||||
|
|
||||||
group("test") {
|
group("test") {
|
||||||
testonly = true
|
testonly = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# We want to make sure to only enable this fuzzer on platforms that have a CQ
|
||||||
|
# bot so that the mojom target list is maintained up-to-date.
|
||||||
|
# Similarly, if something goes wrong with those targets, this will "only" break
|
||||||
|
# fuzzer CQ bots, so we this allows for damage control.
|
||||||
|
# crbug.com/343669713: enable this on Windows once the Linux version sticks in.
|
||||||
|
renderer_ipc_fuzzing_enabled =
|
||||||
|
fuzzing_engine_supports_custom_main && is_linux && enable_mojom_fuzzer
|
||||||
|
|
||||||
if (fuzzing_engine_supports_custom_main) {
|
if (fuzzing_engine_supports_custom_main) {
|
||||||
source_set("renderer_in_process_fuzzer_runner") {
|
source_set("renderer_in_process_fuzzer_runner") {
|
||||||
testonly = true
|
testonly = true
|
||||||
@ -25,164 +32,77 @@ if (fuzzing_engine_supports_custom_main) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# As for now, we cannot compile this fuzzer when `dcheck_always_on=true`,
|
if (renderer_ipc_fuzzing_enabled) {
|
||||||
# because InProcessFuzzer aren't running properly. See crbug.com/40949031.
|
_mojolpm_deps = []
|
||||||
# Relatedly, we are also checking for `fuzzing_engine_supports_custom_main`
|
foreach(target, browser_exposed_mojom_targets) {
|
||||||
# because this is a necessary condition to most of the in_process_fuzzer
|
_mojolpm_deps += [ "${target}_mojolpm" ]
|
||||||
# dependencies, which we are heavily relying upon here.
|
}
|
||||||
if (!is_android && !dcheck_always_on && fuzzing_engine_supports_custom_main) {
|
|
||||||
|
# This tool aims at replicating an environment similar to how
|
||||||
|
# in_process_fuzzer are running, so that we can fetch a list of mojom
|
||||||
|
# interfaces that make sense for `renderer_in_process_mojolpm_fuzzer`.
|
||||||
executable("ipc_interfaces_dumper") {
|
executable("ipc_interfaces_dumper") {
|
||||||
testonly = true
|
testonly = true
|
||||||
sources = [
|
defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
|
||||||
# We include those files so that we take into consideration the exact
|
sources = [ "ipc_fuzzing/ipc_interfaces_dumper.cc" ]
|
||||||
# same setup as in_process_fuzzer, including the runtime flags. This is
|
|
||||||
# important because this can have an effect on which interfaces are
|
|
||||||
# being exposed.
|
|
||||||
"../in_process_fuzzer.cc",
|
|
||||||
"../in_process_fuzzer.h",
|
|
||||||
"ipc_fuzzing/ipc_interfaces_dumper.cc",
|
|
||||||
]
|
|
||||||
deps = [
|
deps = [
|
||||||
"//chrome/test:chrome_test_launcher",
|
"//base",
|
||||||
|
"//chrome/test:browser_tests_runner",
|
||||||
"//chrome/test:test_support",
|
"//chrome/test:test_support",
|
||||||
"//chrome/test/fuzzing:in_process_fuzzer_buildflags",
|
|
||||||
"//content/test:test_support",
|
"//content/test:test_support",
|
||||||
|
|
||||||
# This is so that in_process_fuzzer internals work, but
|
|
||||||
# `ipc_interfaces_dumper` is not recognized as an actual fuzzer.
|
|
||||||
"//testing/libfuzzer:fuzzing_engine_no_main_core",
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
action("renderer_in_process_mojolpm_fuzzer_generator") {
|
action("renderer_in_process_mojolpm_fuzzer_generator") {
|
||||||
testonly = true
|
testonly = true
|
||||||
|
deps = [ ":ipc_interfaces_dumper" ]
|
||||||
|
depfile = "$target_out_dir/$target_name.d"
|
||||||
|
inputs = []
|
||||||
|
foreach(target, browser_exposed_mojom_targets) {
|
||||||
|
inputs += [ get_label_info(target, "target_gen_dir") + "/" +
|
||||||
|
get_label_info(target, "name") + ".build_metadata" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
# We cannot use the GN `metadata` mechanism here, because our initial
|
||||||
|
# deps could depend on other mojom targets which would also generate some
|
||||||
|
# metadata, but we would actually not depend on their `mojolpm` variant.
|
||||||
|
# Doing things the current way allows for ensuring that we are only listing
|
||||||
|
# meta files for mojolpm targets we directly depend upon.
|
||||||
|
_metafiles = []
|
||||||
|
foreach(file, inputs) {
|
||||||
|
_metafiles += [ rebase_path(file, root_build_dir) ]
|
||||||
|
}
|
||||||
|
write_file("$target_gen_dir/metadata", _metafiles)
|
||||||
|
|
||||||
script = "//chrome/test/fuzzing/renderer_fuzzing/ipc_fuzzing/generate_testcase.py"
|
script = "//chrome/test/fuzzing/renderer_fuzzing/ipc_fuzzing/generate_testcase.py"
|
||||||
args = [
|
args = [
|
||||||
"-n",
|
"-p",
|
||||||
"renderer_in_process_mojolpm_fuzzer",
|
rebase_path("${root_build_dir}/ipc_interfaces_dumper", root_build_dir),
|
||||||
|
"-i",
|
||||||
|
rebase_path("${target_gen_dir}/interfaces.json", root_build_dir),
|
||||||
|
"-r",
|
||||||
|
rebase_path(root_gen_dir, root_build_dir),
|
||||||
|
"-m",
|
||||||
|
rebase_path("$target_gen_dir/metadata", root_build_dir),
|
||||||
|
"-t",
|
||||||
|
rebase_path("${target_gen_dir}/testcase.h", root_build_dir),
|
||||||
"-d",
|
"-d",
|
||||||
rebase_path("${target_gen_dir}/", root_gen_dir),
|
rebase_path("${target_gen_dir}/", root_gen_dir),
|
||||||
"-o",
|
"-n",
|
||||||
rebase_path("${target_gen_dir}/testcase.h", root_build_dir),
|
"renderer_in_process_mojolpm_fuzzer",
|
||||||
"-c",
|
"-f",
|
||||||
|
rebase_path(depfile, root_build_dir),
|
||||||
]
|
]
|
||||||
foreach(interface, context_browser_exposed_interfaces) {
|
outputs = [
|
||||||
args += [ interface[1] ]
|
"${target_gen_dir}/interfaces.json",
|
||||||
}
|
"${target_gen_dir}/testcase.h",
|
||||||
args += [ "-p" ]
|
]
|
||||||
foreach(interface, process_browser_exposed_interfaces) {
|
deps += _mojolpm_deps
|
||||||
args += [ interface[1] ]
|
|
||||||
}
|
|
||||||
outputs = [ "${target_gen_dir}/testcase.h" ]
|
|
||||||
}
|
}
|
||||||
in_process_renderer_mojolpm_generated_fuzzer(
|
in_process_renderer_mojolpm_generated_fuzzer(
|
||||||
"renderer_in_process_mojolpm_fuzzer") {
|
"renderer_in_process_mojolpm_fuzzer") {
|
||||||
sources = [ "renderer_in_process_mojolpm_fuzzer.cc" ]
|
sources = [ "renderer_in_process_mojolpm_fuzzer.cc" ]
|
||||||
|
|
||||||
interfaces = context_browser_exposed_interfaces
|
interface_file = "${target_gen_dir}/interfaces.json"
|
||||||
interfaces += process_browser_exposed_interfaces
|
|
||||||
|
|
||||||
_interfaces_deps = [
|
|
||||||
"//chrome/browser/lens/core/mojom:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/media:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/new_tab_page/modules/file_suggestion:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/new_tab_page/modules/photos:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/new_tab_page/modules/v2/history_clusters:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/new_tab_page/modules/v2/tab_resumption:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/access_code_cast:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/app_home:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/app_service_internals:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/bluetooth_internals:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/connectors_internals:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/discards:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/downloads:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/internals/user_education:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/location_internals:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/new_tab_page:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/new_tab_page/foo:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/new_tab_page_third_party:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/omnibox:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/privacy_sandbox:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/reset_password:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/search_engine_choice:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/segmentation_internals:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/side_panel/bookmarks:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/side_panel/customize_chrome:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/side_panel/reading_list:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/suggest_internals:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/tab_search:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/tab_strip:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/usb_internals:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/browser/ui/webui/web_app_internals:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/common:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/common/accessibility:mojo_bindings_mojolpm",
|
|
||||||
"//chrome/common/cart:mojo_bindings_mojolpm",
|
|
||||||
"//components/browsing_topics/mojom:mojo_bindings_mojolpm",
|
|
||||||
"//components/commerce/core/internals/mojom:mojo_bindings_mojolpm",
|
|
||||||
"//components/dom_distiller/content/common/mojom:mojom_mojolpm",
|
|
||||||
"//components/history_clusters/history_clusters_internals/webui:mojo_bindings_mojolpm",
|
|
||||||
"//components/metrics/public/mojom:call_stack_mojo_bindings_mojolpm",
|
|
||||||
"//components/metrics/public/mojom:single_sample_metrics_mojo_bindings_mojolpm",
|
|
||||||
"//components/network_hints/common:mojo_bindings_mojolpm",
|
|
||||||
"//components/no_state_prefetch/common:mojo_bindings_mojolpm",
|
|
||||||
"//components/optimization_guide/optimization_guide_internals/webui:mojo_bindings_mojolpm",
|
|
||||||
"//components/page_image_service/mojom:mojo_bindings_mojolpm",
|
|
||||||
"//components/performance_manager/public/mojom:mojom_mojolpm",
|
|
||||||
"//components/safe_browsing/content/common:interfaces_mojolpm",
|
|
||||||
"//components/site_engagement/core/mojom:mojo_bindings_mojolpm",
|
|
||||||
"//components/spellcheck/common:interfaces_mojolpm",
|
|
||||||
"//components/translate/content/common:common_mojolpm",
|
|
||||||
"//content/browser/attribution_reporting:internals_mojo_bindings_mojolpm",
|
|
||||||
"//content/browser/indexed_db:internals_mojo_bindings_mojolpm",
|
|
||||||
"//content/browser/private_aggregation:mojo_bindings_mojolpm",
|
|
||||||
"//content/browser/process_internals:mojo_bindings_mojolpm",
|
|
||||||
"//content/browser/tracing/trace_report:mojo_bindings_mojolpm",
|
|
||||||
"//content/browser/xr/webxr_internals/mojom:mojo_bindings_mojolpm",
|
|
||||||
"//content/common:mojo_bindings_mojolpm",
|
|
||||||
"//device/gamepad/public/mojom:mojom_mojolpm",
|
|
||||||
"//device/vr/public/mojom:vr_service_mojolpm",
|
|
||||||
"//extensions/common/api:mojom_mojolpm",
|
|
||||||
"//media/capture/mojom:image_capture_mojolpm",
|
|
||||||
"//media/capture/mojom:video_capture_mojolpm",
|
|
||||||
"//media/midi:mojo_mojolpm",
|
|
||||||
"//media/mojo/mojom:mojom_mojolpm",
|
|
||||||
"//media/mojo/mojom:remoting_mojolpm",
|
|
||||||
"//media/mojo/mojom:speech_recognition_mojolpm",
|
|
||||||
"//media/mojo/mojom:web_speech_recognition_mojolpm",
|
|
||||||
"//services/device/public/mojom:mojom_mojolpm",
|
|
||||||
"//services/image_annotation/public/mojom:mojom_mojolpm",
|
|
||||||
"//services/network/public/mojom:cookies_mojom_mojolpm",
|
|
||||||
"//services/network/public/mojom:mojom_mojolpm",
|
|
||||||
"//services/network/public/mojom:url_loader_base_mojolpm",
|
|
||||||
"//services/resource_coordinator/public/mojom:mojom_mojolpm",
|
|
||||||
"//services/screen_ai/public/mojom:mojom_mojolpm",
|
|
||||||
"//services/shape_detection/public/mojom:mojom_mojolpm",
|
|
||||||
"//services/viz/public/mojom:mojom_mojolpm",
|
|
||||||
"//storage/browser/quota:mojo_bindings_mojolpm",
|
|
||||||
"//third_party/blink/public/mojom:android_mojo_bindings_mojolpm",
|
|
||||||
"//third_party/blink/public/mojom:authenticator_test_mojo_bindings_mojolpm",
|
|
||||||
"//third_party/blink/public/mojom:embedded_frame_sink_mojo_bindings_mojolpm",
|
|
||||||
"//third_party/blink/public/mojom:mojom_core_mojolpm",
|
|
||||||
"//third_party/blink/public/mojom:mojom_modules_mojolpm",
|
|
||||||
"//third_party/blink/public/mojom:mojom_platform_mojolpm",
|
|
||||||
"//third_party/blink/public/mojom:web_bluetooth_mojo_bindings_mojolpm",
|
|
||||||
"//third_party/blink/public/mojom/gpu:gpu_mojolpm",
|
|
||||||
"//third_party/blink/public/mojom/origin_trial_state:origin_trial_state_mojolpm",
|
|
||||||
"//third_party/blink/public/mojom/quota:quota_mojolpm",
|
|
||||||
"//third_party/blink/public/mojom/usb:usb_mojolpm",
|
|
||||||
"//ui/webui/resources/cr_components/app_management:mojo_bindings_mojolpm",
|
|
||||||
"//ui/webui/resources/cr_components/certificate_manager:mojom_mojolpm",
|
|
||||||
"//ui/webui/resources/cr_components/color_change_listener:mojom_mojolpm",
|
|
||||||
"//ui/webui/resources/cr_components/commerce:mojo_bindings_mojolpm",
|
|
||||||
"//ui/webui/resources/cr_components/customize_color_scheme_mode:mojom_mojolpm",
|
|
||||||
"//ui/webui/resources/cr_components/customize_themes:mojom_mojolpm",
|
|
||||||
"//ui/webui/resources/cr_components/help_bubble:mojo_bindings_mojolpm",
|
|
||||||
"//ui/webui/resources/cr_components/history_clusters:mojo_bindings_mojolpm",
|
|
||||||
"//ui/webui/resources/cr_components/most_visited:mojom_mojolpm",
|
|
||||||
"//ui/webui/resources/cr_components/searchbox:mojo_bindings_mojolpm",
|
|
||||||
"//ui/webui/resources/cr_components/theme_color_picker:mojom_mojolpm",
|
|
||||||
"//ui/webui/resources/js/browser_command:mojo_bindings_mojolpm",
|
|
||||||
"//ui/webui/resources/js/metrics_reporter:mojo_bindings_mojolpm",
|
|
||||||
]
|
|
||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
":renderer_in_process_mojolpm_fuzzer_generator",
|
":renderer_in_process_mojolpm_fuzzer_generator",
|
||||||
@ -193,8 +113,10 @@ if (!is_android && !dcheck_always_on && fuzzing_engine_supports_custom_main) {
|
|||||||
"//testing/libfuzzer/proto:url_proto_converter",
|
"//testing/libfuzzer/proto:url_proto_converter",
|
||||||
"//third_party/blink/public/common:storage_key_proto_converter",
|
"//third_party/blink/public/common:storage_key_proto_converter",
|
||||||
]
|
]
|
||||||
deps += _interfaces_deps
|
|
||||||
|
|
||||||
proto_deps = _interfaces_deps
|
deps += _mojolpm_deps
|
||||||
|
|
||||||
|
proto_deps = [ ":renderer_in_process_mojolpm_fuzzer_generator" ]
|
||||||
|
proto_deps += _mojolpm_deps
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,40 @@
|
|||||||
|
|
||||||
This script must be used with MojoLPMGenerator and a RendererFuzzer. It
|
This script must be used with MojoLPMGenerator and a RendererFuzzer. It
|
||||||
generates code to handle interface creation requested by MojoLPM by using the
|
generates code to handle interface creation requested by MojoLPM by using the
|
||||||
interface brokers provided by the internal RendererFuzzer mechanism.
|
`ipc_interfaces_dumper` binary. It then formats a JSON file that
|
||||||
|
MojoLPMGenerator will understand.
|
||||||
|
|
||||||
|
JSON Format:
|
||||||
|
{
|
||||||
|
# Those are the context (frame, document...) bound interfaces.
|
||||||
|
"context_interfaces": [
|
||||||
|
[
|
||||||
|
"//path/to/mojom.mojom",
|
||||||
|
"qualified.interface.name",
|
||||||
|
"{Associated,}Remote",
|
||||||
|
],
|
||||||
|
...
|
||||||
|
],
|
||||||
|
# Those are the process bound interfaces.
|
||||||
|
"process_interfaces": [
|
||||||
|
{
|
||||||
|
"//path/to/mojom.mojom",
|
||||||
|
"qualified.interface.name",
|
||||||
|
"{Associated,}Remote",
|
||||||
|
},
|
||||||
|
...
|
||||||
|
],
|
||||||
|
# Those are the format MojoLPMGenerator undertands.
|
||||||
|
# This groups all interfaces together.
|
||||||
|
"interfaces": [
|
||||||
|
{
|
||||||
|
"gen/path/to/generator/file.mojom-module",
|
||||||
|
"qualified.interface.name",
|
||||||
|
"{Associated,}Remote",
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
This script uses the jinja2 and the `testcase.h.tmpl` template to generate C++
|
This script uses the jinja2 and the `testcase.h.tmpl` template to generate C++
|
||||||
code. A class named `RendererTestcase` will be created.
|
code. A class named `RendererTestcase` will be created.
|
||||||
@ -15,45 +48,270 @@ code. A class named `RendererTestcase` will be created.
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import abc
|
|
||||||
import argparse
|
import argparse
|
||||||
import dataclasses
|
import json
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
import re
|
import re
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import tempfile
|
||||||
import typing
|
import typing
|
||||||
import enum
|
|
||||||
|
|
||||||
# Copied from //mojo/public/tools/mojom/mojom/fileutil.py.
|
|
||||||
def AddLocalRepoThirdPartyDirToModulePath():
|
|
||||||
"""Helper function to find the top-level directory of this script's repository
|
|
||||||
assuming the script falls somewhere within a 'chrome' directory, and insert
|
|
||||||
the top-level 'third_party' directory early in the module search path. Used to
|
|
||||||
ensure that third-party dependencies provided within the repository itself
|
|
||||||
(e.g. Chromium sources include snapshots of jinja2 and ply) are preferred over
|
|
||||||
locally installed system library packages."""
|
|
||||||
def _GetDirAbove(dirname: str):
|
|
||||||
"""Returns the directory "above" this file containing |dirname| (which must
|
|
||||||
also be "above" this file)."""
|
|
||||||
path = os.path.abspath(__file__)
|
|
||||||
while True:
|
|
||||||
path, tail = os.path.split(path)
|
|
||||||
if not tail:
|
|
||||||
return None
|
|
||||||
if tail == dirname:
|
|
||||||
return path
|
|
||||||
|
|
||||||
toplevel_dir = _GetDirAbove('chrome')
|
def _GetDirAbove(dirname: str):
|
||||||
if toplevel_dir:
|
"""Returns the directory "above" this file containing |dirname| (which must
|
||||||
sys.path.insert(1, os.path.join(toplevel_dir, 'third_party'))
|
also be "above" this file)."""
|
||||||
|
path = os.path.abspath(__file__)
|
||||||
|
while True:
|
||||||
|
path, tail = os.path.split(path)
|
||||||
|
if not tail:
|
||||||
|
return None
|
||||||
|
if tail == dirname:
|
||||||
|
return path
|
||||||
|
|
||||||
# This is needed in order to be able to import jinja2.
|
|
||||||
AddLocalRepoThirdPartyDirToModulePath()
|
|
||||||
|
|
||||||
|
SOURCE_DIR = _GetDirAbove('chrome')
|
||||||
|
|
||||||
|
sys.path.insert(1, os.path.join(SOURCE_DIR, 'third_party'))
|
||||||
|
sys.path.append(os.path.join(SOURCE_DIR, 'build'))
|
||||||
|
sys.path.append(os.path.join(SOURCE_DIR, 'mojo/public/tools/mojom/'))
|
||||||
|
|
||||||
|
from mojom.parse import parser as mojom_parser, ast
|
||||||
|
import action_helpers
|
||||||
import jinja2
|
import jinja2
|
||||||
|
|
||||||
|
XVFB_PATH = os.path.join(SOURCE_DIR, 'testing/xvfb.py')
|
||||||
|
|
||||||
|
|
||||||
|
def strip_end(text: str, suffix: str) -> str:
|
||||||
|
"""Similar to python 3.9 `removesuffix` function.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
text: input text.
|
||||||
|
suffix: the suffix to remove if present.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
the input string with suffix removed if present.
|
||||||
|
"""
|
||||||
|
if suffix and text.endswith(suffix):
|
||||||
|
return text[:-len(suffix)]
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def get_all_interfaces(metadata_file: str) -> typing.List[str]:
|
||||||
|
"""Returns the list of every mojo interfaces in src_dir. Recurses through
|
||||||
|
subdirectories.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
src_dir: the chromium source directory.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
the list of paths to mojom interfaces.
|
||||||
|
"""
|
||||||
|
res = []
|
||||||
|
with open(metadata_file, 'r', encoding='utf-8') as file:
|
||||||
|
lines = [line.rstrip() for line in file]
|
||||||
|
for line in lines:
|
||||||
|
with open(line, 'r') as metadata:
|
||||||
|
data = json.load(metadata)
|
||||||
|
for mojom_file in data['sources']:
|
||||||
|
if mojom_file.endswith('.mojom'):
|
||||||
|
path = os.path.join(os.path.dirname(line), mojom_file)
|
||||||
|
path = os.path.abspath(path)
|
||||||
|
res.append(path)
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def is_defined_in_module(qualified_name: str, interface: ast.Mojom) -> bool:
|
||||||
|
namespace = ".".join(qualified_name.split('.')[:-1])
|
||||||
|
name = qualified_name.split('.')[-1]
|
||||||
|
if not interface.module:
|
||||||
|
return False
|
||||||
|
m_namespace = str(interface.module.mojom_namespace)
|
||||||
|
if m_namespace != namespace:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not interface.definition_list:
|
||||||
|
return False
|
||||||
|
for definition in interface.definition_list:
|
||||||
|
if (isinstance(definition, ast.Interface) and
|
||||||
|
str(definition.mojom_name) == name):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def find_matching_interface(qualified_name: str,
|
||||||
|
modules: typing.List[ast.Mojom]) -> str:
|
||||||
|
"""Finds the correct mojom file for the given interface. The interface name
|
||||||
|
must be qualified.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
qualified_name: the qualified interface name (e.g.
|
||||||
|
'blink.mojom.BlobRegistry').
|
||||||
|
modules: the list of parsed mojom modules.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
the path to the mojom file corresponding to the input interface.
|
||||||
|
"""
|
||||||
|
for module in modules:
|
||||||
|
if is_defined_in_module(qualified_name, module):
|
||||||
|
return module.module.filename
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_interface_deps_complete(interfaces: typing.List[str],
|
||||||
|
modules: typing.List[ast.Mojom],
|
||||||
|
build_dir: str):
|
||||||
|
"""Ensures that all the interfaces can be fetched from the parsed mojom
|
||||||
|
modules.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
interfaces: the list of interfaces (qualified names).
|
||||||
|
modules: the list of mojom modules to search into.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
Exception: if at least one interface could not be found.
|
||||||
|
"""
|
||||||
|
missing_interfaces = []
|
||||||
|
for interface in interfaces:
|
||||||
|
res = find_matching_interface(interface, modules)
|
||||||
|
if not res:
|
||||||
|
missing_interfaces.append(interface)
|
||||||
|
if len(missing_interfaces) != 0:
|
||||||
|
raise Exception('Missing browser exposed targets for the following '
|
||||||
|
'interfaces:\n'
|
||||||
|
f'{missing_interfaces}\n'
|
||||||
|
'Please add the corresponding targets to '
|
||||||
|
'`//chrome/browser_exposed_mojom_targets.gni`.')
|
||||||
|
|
||||||
|
|
||||||
|
def handle_interfaces(interfaces,
|
||||||
|
mojom_files: typing.List[ast.Mojom],
|
||||||
|
source_path: str,
|
||||||
|
output):
|
||||||
|
"""Finds the mojom files for the given interfaces and append the formatted
|
||||||
|
result to the output list.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
interfaces: the interfaces to handle.
|
||||||
|
mojom_files: the list of parsed mojom files to look into.
|
||||||
|
source_path: the path to chromium's root source directory.
|
||||||
|
output: the output list.
|
||||||
|
"""
|
||||||
|
for interface in interfaces:
|
||||||
|
qualified_name = interface['qualified_name']
|
||||||
|
interface_type = interface['type']
|
||||||
|
path = pathlib.Path(find_matching_interface(qualified_name, mojom_files))
|
||||||
|
path = path.relative_to(source_path)
|
||||||
|
output.append([
|
||||||
|
f"//{path}", qualified_name, interface_type
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def filter_data(data):
|
||||||
|
"""Filters the JSON data. As for now, we filter out:
|
||||||
|
- AssociatedRemote
|
||||||
|
- Duplicate interfaces for context and process interfaces.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data: the JSON data.
|
||||||
|
"""
|
||||||
|
data_filter = lambda x : x['type'] != 'AssociatedRemote'
|
||||||
|
data['context_interfaces'] = list(filter(data_filter,
|
||||||
|
data['context_interfaces']))
|
||||||
|
data['process_interfaces'] = list(filter(data_filter,
|
||||||
|
data['process_interfaces']))
|
||||||
|
ctx_interfaces = [s['qualified_name'] for s in data['context_interfaces']]
|
||||||
|
data_filter = lambda x: x['qualified_name'] not in ctx_interfaces
|
||||||
|
data['process_interfaces'] = list(filter(data_filter,
|
||||||
|
data['process_interfaces']))
|
||||||
|
|
||||||
|
|
||||||
|
def run_ipc_dumper(dumper_path: str, out_file: str):
|
||||||
|
"""This runs the ipc_dumper executable at `dumper_path` and redirects its
|
||||||
|
output to `out_file` so that this tool can use it to generate the list of
|
||||||
|
interfaces.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
dumper_path: path to the `ipc_interfaces_dumper` executable.
|
||||||
|
out_file: the file to which we'll dump the interfaces.
|
||||||
|
"""
|
||||||
|
env = os.environ.copy()
|
||||||
|
env["IPC_DUMP_PATH"] = out_file
|
||||||
|
# Since we're running these at compile time, we need to make sure this will
|
||||||
|
# run regardless of the building flags being used.
|
||||||
|
# When enabling ASAN, we have a `detect_ord_violation` issue when running
|
||||||
|
# this tool.
|
||||||
|
env["ASAN_OPTIONS"] = 'detect_odr_violation=0'
|
||||||
|
args = [XVFB_PATH, os.path.abspath(dumper_path)]
|
||||||
|
subprocess.run(args, capture_output=True, env=env, check=True)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_interfaces(ipc_interfaces_dumper: str,
|
||||||
|
interfaces_f: str,
|
||||||
|
gen_dir: str,
|
||||||
|
metadata_file: str,
|
||||||
|
depfile: str):
|
||||||
|
"""Generates the appropriate interfaces file given the output of the
|
||||||
|
`ipc_interfaces_dumper`.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
ipc_interfaces_dumper: the path to the `ipc_interfaces_dumper` binary.
|
||||||
|
interfaces_f: the output path to the JSON interfaces file.
|
||||||
|
gen_dir: the path to the root gen directory.
|
||||||
|
metadata_file: the path to the mojo metadata file.
|
||||||
|
depfile: the depfile to write to.
|
||||||
|
"""
|
||||||
|
interfaces = get_all_interfaces(metadata_file)
|
||||||
|
parsed_interfaces = []
|
||||||
|
for interface in interfaces:
|
||||||
|
with open(interface, 'r', encoding="utf-8") as f:
|
||||||
|
parsed_interfaces.append(mojom_parser.Parse(f.read(), interface))
|
||||||
|
output = {"context_interfaces": [], "process_interfaces": []}
|
||||||
|
with tempfile.NamedTemporaryFile() as input_file:
|
||||||
|
run_ipc_dumper(ipc_interfaces_dumper, input_file.name)
|
||||||
|
with open(input_file.name, 'r') as in_f:
|
||||||
|
data = json.load(in_f)
|
||||||
|
filter_data(data)
|
||||||
|
all_interfaces = data['context_interfaces'] + data['process_interfaces']
|
||||||
|
qualified_names = [e['qualified_name'] for e in all_interfaces]
|
||||||
|
ensure_interface_deps_complete(qualified_names,
|
||||||
|
parsed_interfaces,
|
||||||
|
os.path.join(gen_dir, os.pardir))
|
||||||
|
handle_interfaces(data['context_interfaces'],
|
||||||
|
parsed_interfaces,
|
||||||
|
SOURCE_DIR,
|
||||||
|
output['context_interfaces'])
|
||||||
|
handle_interfaces(data['process_interfaces'],
|
||||||
|
parsed_interfaces,
|
||||||
|
SOURCE_DIR,
|
||||||
|
output['process_interfaces'])
|
||||||
|
|
||||||
|
# MojoLPMGenerator expects a particular format for generating MojoLPM
|
||||||
|
# boilerplate. This part will generate the expected format and rebase the
|
||||||
|
# mojom module paths in order for MojoLPMGenerator to be able to find them.
|
||||||
|
output['interfaces'] = []
|
||||||
|
for interface in output['context_interfaces'] + output['process_interfaces']:
|
||||||
|
path = interface[0]
|
||||||
|
path = os.path.join(gen_dir, path.lstrip('/')) + '-module'
|
||||||
|
output['interfaces'].append([
|
||||||
|
path, interface[1], interface[2]
|
||||||
|
])
|
||||||
|
with action_helpers.atomic_output(interfaces_f, mode="w") as f:
|
||||||
|
json.dump(output, f)
|
||||||
|
|
||||||
|
# Now, we want to write the depfile so that ninja knows that we're depending
|
||||||
|
# on the mojom files. If one gets modified, we want to re-run this action.
|
||||||
|
all_interfaces = output['context_interfaces'] + output['process_interfaces']
|
||||||
|
paths = [i[0].lstrip('//') for i in all_interfaces]
|
||||||
|
paths = [pathlib.Path(os.path.join(SOURCE_DIR, p)) for p in paths]
|
||||||
|
action_helpers.write_depfile(depfile,
|
||||||
|
interfaces_f,
|
||||||
|
[os.path.relpath(p) for p in paths])
|
||||||
|
|
||||||
|
|
||||||
def split_interface_name(interface: str):
|
def split_interface_name(interface: str):
|
||||||
"""Helper that splits a qualified mojo interface name into a dictionary
|
"""Helper that splits a qualified mojo interface name into a dictionary
|
||||||
containing the key 'name' that contains the name of the interface, and the
|
containing the key 'name' that contains the name of the interface, and the
|
||||||
@ -106,23 +364,50 @@ def camel_to_snake_case(name: str) -> str:
|
|||||||
# character but only add the '_'.
|
# character but only add the '_'.
|
||||||
return re.sub(r"(?<!^)(?=[A-Z])", "_", name).lower()
|
return re.sub(r"(?<!^)(?=[A-Z])", "_", name).lower()
|
||||||
|
|
||||||
|
|
||||||
|
def generate_testcase(interfaces_f: str,
|
||||||
|
fuzzer_dir: str,
|
||||||
|
fuzzer_name: str,
|
||||||
|
testcase_f: str):
|
||||||
|
"""Generates the testcase file given the interface list and the
|
||||||
|
MojoLPMGenerator fuzzer name.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
interfaces_f: the path to the JSON interface file.
|
||||||
|
fuzzer_dir: the path to the fuzzer directory.
|
||||||
|
fuzzer_name: the name of the MojoLPM fuzzer.
|
||||||
|
testcase_f: the output path to the testcase .h file.
|
||||||
|
"""
|
||||||
|
template_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
environment = jinja2.Environment(loader=jinja2.FileSystemLoader(
|
||||||
|
template_dir))
|
||||||
|
template = environment.get_template('testcase.h.tmpl')
|
||||||
|
fuzzer_path = os.path.join(fuzzer_dir, fuzzer_name)
|
||||||
|
fuzzer_name = snake_to_camel_case(fuzzer_name)
|
||||||
|
mojolpm_classname = f"mojolpmgenerator::{fuzzer_name}Testcase"
|
||||||
|
with open(interfaces_f, 'r') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
context = [c[1] for c in data['context_interfaces']]
|
||||||
|
process = [p[1] for p in data['process_interfaces']]
|
||||||
|
context = {
|
||||||
|
"filename": testcase_f,
|
||||||
|
"mojolpm_generator_filepath": f"{fuzzer_path}.h",
|
||||||
|
"mojolpm_generator_classname": mojolpm_classname,
|
||||||
|
"process_interfaces": [split_interface_name(p) for p in process],
|
||||||
|
"context_interfaces": [split_interface_name(c) for c in context],
|
||||||
|
}
|
||||||
|
with action_helpers.atomic_output(testcase_f, mode="w") as f:
|
||||||
|
f.write(template.render(context))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description='Generate an IPC fuzzer based on MojoLPM Generator.')
|
description='Generate an IPC fuzzer based on MojoLPM Generator.')
|
||||||
parser.add_argument(
|
|
||||||
'-c',
|
|
||||||
'--context',
|
|
||||||
default=[],
|
|
||||||
nargs='+',
|
|
||||||
required=True,
|
|
||||||
help="Context bound interfaces to fuzz.")
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-p',
|
'-p',
|
||||||
'--process',
|
'--path',
|
||||||
default=[],
|
|
||||||
nargs='+',
|
|
||||||
required=True,
|
required=True,
|
||||||
help="Process bound interfaces to fuzz.")
|
help="The path to ipc_interfaces_dumper binary.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-d',
|
'-d',
|
||||||
'--fuzzer_dir',
|
'--fuzzer_dir',
|
||||||
@ -135,28 +420,42 @@ def main():
|
|||||||
help="""The name of the MojoLPMGenerator fuzzing target.
|
help="""The name of the MojoLPMGenerator fuzzing target.
|
||||||
This will used to deduce the name of the generated MojoLPM testcase.""")
|
This will used to deduce the name of the generated MojoLPM testcase.""")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-o',
|
'-t',
|
||||||
'--output',
|
'--testcase-output-path',
|
||||||
required=True,
|
required=True,
|
||||||
help="Output file name.")
|
help="The path where the testcase file will be written to.")
|
||||||
|
parser.add_argument(
|
||||||
|
'-i',
|
||||||
|
'--interface-output-path',
|
||||||
|
required=True,
|
||||||
|
help="The path where the interface file will be written to.")
|
||||||
|
parser.add_argument(
|
||||||
|
'-r',
|
||||||
|
'--root-gen-dir',
|
||||||
|
required=True,
|
||||||
|
help="The path to the root gen dir.")
|
||||||
|
parser.add_argument(
|
||||||
|
'-m',
|
||||||
|
'--metadata-file',
|
||||||
|
required=True,
|
||||||
|
help="Path to the metadata file.")
|
||||||
|
parser.add_argument(
|
||||||
|
'-f',
|
||||||
|
'--depfile',
|
||||||
|
required=True,
|
||||||
|
help="The path to the depfile.")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
template_dir = os.path.dirname(os.path.abspath(__file__))
|
generate_interfaces(args.path,
|
||||||
environment = jinja2.Environment(loader=jinja2.FileSystemLoader(
|
args.interface_output_path,
|
||||||
template_dir))
|
args.root_gen_dir,
|
||||||
template = environment.get_template('testcase.h.tmpl')
|
args.metadata_file,
|
||||||
fuzzer_path = os.path.join(args.fuzzer_dir, args.name)
|
args.depfile)
|
||||||
fuzzer_name = snake_to_camel_case(args.name)
|
generate_testcase(args.interface_output_path,
|
||||||
mojolpm_classname = f"mojolpmgenerator::{fuzzer_name}Testcase"
|
args.fuzzer_dir,
|
||||||
context = {
|
args.name,
|
||||||
"filename": args.output,
|
args.testcase_output_path)
|
||||||
"mojolpm_generator_filepath": f"{fuzzer_path}.h",
|
|
||||||
"mojolpm_generator_classname": mojolpm_classname,
|
|
||||||
"process_interfaces": [split_interface_name(p) for p in args.process],
|
|
||||||
"context_interfaces": [split_interface_name(c) for c in args.context],
|
|
||||||
}
|
|
||||||
with pathlib.Path(args.output).open(mode="w") as f:
|
|
||||||
f.write(template.render(context))
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@ -14,12 +14,14 @@
|
|||||||
#include "base/strings/escape.h"
|
#include "base/strings/escape.h"
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
#include "base/test/bind.h"
|
#include "base/test/bind.h"
|
||||||
|
#include "base/threading/thread_restrictions.h"
|
||||||
#include "base/time/time.h"
|
#include "base/time/time.h"
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
#include "chrome/browser/ui/browser.h"
|
#include "chrome/browser/ui/browser.h"
|
||||||
|
#include "chrome/test/base/in_process_browser_test.h"
|
||||||
#include "chrome/test/base/ui_test_utils.h"
|
#include "chrome/test/base/ui_test_utils.h"
|
||||||
#include "chrome/test/fuzzing/in_process_fuzzer.h"
|
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
|
#include "content/public/test/browser_test.h"
|
||||||
|
|
||||||
// Format for the outputted JSON:
|
// Format for the outputted JSON:
|
||||||
// {
|
// {
|
||||||
@ -41,19 +43,6 @@
|
|||||||
// ]
|
// ]
|
||||||
// }
|
// }
|
||||||
|
|
||||||
class IPCInterfaceDumper : public InProcessFuzzer {
|
|
||||||
public:
|
|
||||||
IPCInterfaceDumper() = default;
|
|
||||||
void RunTestOnMainThread() override;
|
|
||||||
|
|
||||||
int Fuzz(const uint8_t* data, size_t size) override { return 0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// We register this tool as an in_process_fuzzer so that it has the exact same
|
|
||||||
// setup as an in_process_fuzzer. Indeed, this is important because this can
|
|
||||||
// have an effect on which interfaces are being exposed.
|
|
||||||
REGISTER_IN_PROCESS_FUZZER(IPCInterfaceDumper)
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void RegisterInterfaces(const std::vector<std::string>& interfaces,
|
void RegisterInterfaces(const std::vector<std::string>& interfaces,
|
||||||
@ -72,7 +61,12 @@ void RegisterInterfaces(const std::vector<std::string>& interfaces,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void IPCInterfaceDumper::RunTestOnMainThread() {
|
class IPCInterfacesDumper : public InProcessBrowserTest {
|
||||||
|
public:
|
||||||
|
IPCInterfacesDumper() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
IN_PROC_BROWSER_TEST_F(IPCInterfacesDumper, DumperTest) {
|
||||||
auto env = base::Environment::Create();
|
auto env = base::Environment::Create();
|
||||||
if (!env->HasVar("IPC_DUMP_PATH")) {
|
if (!env->HasVar("IPC_DUMP_PATH")) {
|
||||||
LOG(ERROR) << "IPC_DUMP_PATH not set. Nothing will be done.";
|
LOG(ERROR) << "IPC_DUMP_PATH not set. Nothing will be done.";
|
||||||
@ -107,6 +101,8 @@ void IPCInterfaceDumper::RunTestOnMainThread() {
|
|||||||
// Write the JSON to a file in the IPC_DUMP_PATH directory.
|
// Write the JSON to a file in the IPC_DUMP_PATH directory.
|
||||||
std::string file_path;
|
std::string file_path;
|
||||||
env->GetVar("IPC_DUMP_PATH", &file_path);
|
env->GetVar("IPC_DUMP_PATH", &file_path);
|
||||||
|
|
||||||
|
base::ScopedAllowBlockingForTesting allow_blocking;
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
base::FilePath filepath = base::FilePath(base::UTF8ToWide(file_path));
|
base::FilePath filepath = base::FilePath(base::UTF8ToWide(file_path));
|
||||||
#else
|
#else
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -196,6 +196,17 @@ template("mojolpm_fuzzer_test") {
|
|||||||
# lists.
|
# lists.
|
||||||
# The remote type must be either "Remote" or "AssociatedRemote".
|
# The remote type must be either "Remote" or "AssociatedRemote".
|
||||||
#
|
#
|
||||||
|
# interface_file
|
||||||
|
# JSON file containing the list of interfaces to generate.
|
||||||
|
# Format:
|
||||||
|
# {
|
||||||
|
# "interfaces": {
|
||||||
|
# ["InterfaceName", "//path/to/interface.mojom", "Remote"],
|
||||||
|
# ["AnotherInterface", "//path/to/another.mojom", "AssociatedRemote" ],
|
||||||
|
# ...
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
#
|
||||||
# deps
|
# deps
|
||||||
# List of dependencies to compile this target.
|
# List of dependencies to compile this target.
|
||||||
#
|
#
|
||||||
@ -236,19 +247,22 @@ template("mojolpm_fuzzer_test") {
|
|||||||
template("mojolpm_generated_fuzzer") {
|
template("mojolpm_generated_fuzzer") {
|
||||||
assert(defined(invoker.sources),
|
assert(defined(invoker.sources),
|
||||||
"\"sources\" must be defined for $target_name")
|
"\"sources\" must be defined for $target_name")
|
||||||
assert(defined(invoker.interfaces),
|
assert(
|
||||||
"\"interfaces\" must be defined for $target_name")
|
defined(invoker.interfaces) || defined(invoker.interface_file),
|
||||||
|
"\"interfaces\" or \"interface_file\" must be defined for $target_name")
|
||||||
|
|
||||||
if (enable_mojom_fuzzer) {
|
if (enable_mojom_fuzzer) {
|
||||||
_target_name = target_name
|
_target_name = target_name
|
||||||
_generate_target_name = _target_name + "_mojolpm_generator_generate"
|
_generate_target_name = _target_name + "_mojolpm_generator_generate"
|
||||||
|
|
||||||
# Generates the correct argument format give invoker.interfaces.
|
if (defined(invoker.interfaces)) {
|
||||||
_script_inputs = []
|
# Generates the correct argument format give invoker.interfaces.
|
||||||
foreach(elt, invoker.interfaces) {
|
_script_inputs = []
|
||||||
_script_inputs +=
|
foreach(elt, invoker.interfaces) {
|
||||||
[ rebase_path("$root_gen_dir/" + elt[0] + "-module", root_build_dir) +
|
_script_inputs +=
|
||||||
":" + elt[1] + ":" + elt[2] ]
|
[ rebase_path("$root_gen_dir/" + elt[0] + "-module",
|
||||||
|
root_build_dir) + ":" + elt[1] + ":" + elt[2] ]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
action(_generate_target_name) {
|
action(_generate_target_name) {
|
||||||
@ -261,8 +275,16 @@ template("mojolpm_generated_fuzzer") {
|
|||||||
deps += invoker.proto_deps
|
deps += invoker.proto_deps
|
||||||
}
|
}
|
||||||
|
|
||||||
args = [ "--input" ]
|
args = []
|
||||||
args += _script_inputs
|
if (defined(invoker.interfaces)) {
|
||||||
|
args += [ "--input" ]
|
||||||
|
args += _script_inputs
|
||||||
|
} else if (defined(invoker.interface_file)) {
|
||||||
|
args += [
|
||||||
|
"-f",
|
||||||
|
rebase_path(invoker.interface_file, root_build_dir),
|
||||||
|
]
|
||||||
|
}
|
||||||
args += [
|
args += [
|
||||||
"--output_file_format",
|
"--output_file_format",
|
||||||
rebase_path("${target_gen_dir}/${_target_name}", root_build_dir),
|
rebase_path("${target_gen_dir}/${_target_name}", root_build_dir),
|
||||||
|
@ -45,6 +45,7 @@ from __future__ import annotations
|
|||||||
import abc
|
import abc
|
||||||
import argparse
|
import argparse
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
import re
|
import re
|
||||||
@ -62,6 +63,7 @@ from mojom import fileutil
|
|||||||
from mojom.generate import module
|
from mojom.generate import module
|
||||||
|
|
||||||
fileutil.AddLocalRepoThirdPartyDirToModulePath()
|
fileutil.AddLocalRepoThirdPartyDirToModulePath()
|
||||||
|
CHROME_SRC_DIR = fileutil._GetDirAbove('mojo')
|
||||||
|
|
||||||
import jinja2
|
import jinja2
|
||||||
|
|
||||||
@ -654,17 +656,48 @@ def build(interface: module.Interface,
|
|||||||
return actions
|
return actions
|
||||||
|
|
||||||
|
|
||||||
|
def get_interface_list_from_file(
|
||||||
|
file_path: str) -> typing.List[typing.List[str]]:
|
||||||
|
"""Reads the JSON input file and returns the interfaces list that it
|
||||||
|
contains.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
file_path: the path to the input file.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
the list of interfaces.
|
||||||
|
"""
|
||||||
|
with open(file_path, 'r') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
return data['interfaces']
|
||||||
|
|
||||||
|
|
||||||
|
def get_interface_list_from_input(
|
||||||
|
interfaces: typing.List[str]) -> typing.List[typing.List[str]]:
|
||||||
|
"""Parses the input list of interfaces and returns a list of list that
|
||||||
|
matches the expected format.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
interfaces: the list of strings listing the interfaces.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
the list of interfaces.
|
||||||
|
"""
|
||||||
|
return [interface.split(':') for interface in interfaces]
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description='Generate MojoLPM proto and cpp/h files.')
|
description='Generate MojoLPM proto and cpp/h files.')
|
||||||
parser.add_argument(
|
group = parser.add_mutually_exclusive_group(required=True)
|
||||||
|
group.add_argument(
|
||||||
'-i',
|
'-i',
|
||||||
'--input',
|
'--input',
|
||||||
default=[],
|
default=[],
|
||||||
nargs='+',
|
nargs='+',
|
||||||
required=True,
|
|
||||||
help="input(s) with format: "
|
help="input(s) with format: "
|
||||||
"path/to/interface.mojom-module:InterfaceName:{Remote|AssociatedRemote}")
|
"path/to/interface.mojom-module:InterfaceName:{Remote|AssociatedRemote}")
|
||||||
|
group.add_argument('-f', '--file', help="")
|
||||||
parser.add_argument('--output_file_format',
|
parser.add_argument('--output_file_format',
|
||||||
required=True,
|
required=True,
|
||||||
help="output file format. Files with extensions '.h' and"
|
help="output file format. Files with extensions '.h' and"
|
||||||
@ -677,11 +710,11 @@ def main():
|
|||||||
[MojoLPMProtoGenerator(output_file),
|
[MojoLPMProtoGenerator(output_file),
|
||||||
MojoLPMCppGenerator(output_file)])
|
MojoLPMCppGenerator(output_file)])
|
||||||
actions = MojoLPMActionSet()
|
actions = MojoLPMActionSet()
|
||||||
for file_interface in args.input:
|
if args.file:
|
||||||
custom_format = file_interface.split(':')
|
interfaces = get_interface_list_from_file(args.file)
|
||||||
if len(custom_format) != 3:
|
else:
|
||||||
print(f"Wrong format: {file_interface}. See help for usage.")
|
interfaces = get_interface_list_from_input(args.input)
|
||||||
return
|
for custom_format in interfaces:
|
||||||
(file, interface_name, remote_type_str) = custom_format
|
(file, interface_name, remote_type_str) = custom_format
|
||||||
if remote_type_str == 'Remote':
|
if remote_type_str == 'Remote':
|
||||||
remote_type = MojoLPMActionType.REMOTE_ACTION
|
remote_type = MojoLPMActionType.REMOTE_ACTION
|
||||||
|
Reference in New Issue
Block a user