0
Files
src/content/browser/browser_interface_broker_impl.h
Paul Semel 8870b09076 content: introduce ipc_interfaces_dumper
This tool can be used to dump the registered browser bound interfaces,
and this patch introduces an API in order to facilitate this work. The
end goal of this is to automatically fuzz the IPC surface. See
crrev.com/c/5490095.

Bug: 40282115
Change-Id: I52526ad5ab03e71dbbd4acc17335fba206de1265
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5472004
Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org>
Reviewed-by: Ken Rockot <rockot@google.com>
Commit-Queue: Paul Semel <paulsemel@chromium.org>
Reviewed-by: Adrian Taylor <adetaylor@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1304908}
2024-05-23 08:05:17 +00:00

114 lines
4.7 KiB
C++

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_BROWSER_INTERFACE_BROKER_IMPL_H_
#define CONTENT_BROWSER_BROWSER_INTERFACE_BROKER_IMPL_H_
#include "base/memory/raw_ptr.h"
#include "content/browser/browser_interface_binders.h"
#include "content/browser/mojo_binder_policy_applier.h"
#include "mojo/public/cpp/bindings/binder_map.h"
#include "mojo/public/cpp/bindings/generic_pending_receiver.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/browser_interface_broker.mojom.h"
namespace content {
// content's implementation of the BrowserInterfaceBroker interface that binds
// interfaces requested by the renderer. Every execution context type (frame,
// worker etc) owns an instance and registers appropriate handlers, called
// "binders" (see internal::PopulateBinderMap and
// internal::PopulateBinderMapWithContext).
//
// By default, BrowserInterfaceBrokerImpl runs the binder that was registered
// for a given interface when the interface is requested. However, in some cases
// such as prerendering pages, it may be desirable to defer running the binder,
// or take another action. Setting a non-null `MojoBinderPolicyApplier` enables
// this behavior.
//
// Note: BrowserInterfaceBrokerImpl will eventually replace the usage of
// InterfaceProvider and browser manifests, as well as DocumentInterfaceBroker.
template <typename ExecutionContextHost, typename InterfaceBinderContext>
class BrowserInterfaceBrokerImpl : public blink::mojom::BrowserInterfaceBroker {
public:
explicit BrowserInterfaceBrokerImpl(ExecutionContextHost* host)
: host_(host) {
// The populate functions here define all the interfaces that will be
// exposed through the broker.
//
// The `host` is a templated type (one of RenderFrameHostImpl,
// ServiceWorkerHost, etc.). which allows the populate steps here to call a
// set of overloaded functions based on that type. Thus each type of `host`
// can expose a different set of interfaces, which is determined statically
// at compile time.
internal::PopulateBinderMap(host, &binder_map_);
internal::PopulateBinderMapWithContext(host, &binder_map_with_context_);
}
// Disallows copy and move operations.
BrowserInterfaceBrokerImpl(const BrowserInterfaceBrokerImpl& other) = delete;
BrowserInterfaceBrokerImpl& operator=(
const BrowserInterfaceBrokerImpl& other) = delete;
BrowserInterfaceBrokerImpl(BrowserInterfaceBrokerImpl&&) = delete;
BrowserInterfaceBrokerImpl& operator=(BrowserInterfaceBrokerImpl&&) = delete;
// blink::mojom::BrowserInterfaceBroker
void GetInterface(mojo::GenericPendingReceiver receiver) override {
DCHECK(receiver.interface_name().has_value());
if (!policy_applier_) {
BindInterface(std::move(receiver));
} else {
std::string interface_name = receiver.interface_name().value();
// base::Unretained is safe because `this` outlives `policy_applier_`.
policy_applier_->ApplyPolicyToNonAssociatedBinder(
interface_name,
base::BindOnce(&BrowserInterfaceBrokerImpl::BindInterface,
base::Unretained(this), std::move(receiver)));
}
}
// Sets MojoBinderPolicyApplier to control when to bind interfaces.
void ApplyMojoBinderPolicies(MojoBinderPolicyApplier* policy_applier) {
DCHECK(policy_applier);
DCHECK(!policy_applier_);
policy_applier_ = policy_applier;
}
// Stops applying policies to binding requests.
void ReleaseMojoBinderPolicies() {
DCHECK(policy_applier_);
// Reset `policy_applier_` to disable capability control.
policy_applier_ = nullptr;
}
void GetBinderMapInterfacesForTesting(std::vector<std::string>& out) {
binder_map_.GetInterfacesForTesting(out);
binder_map_with_context_.GetInterfacesForTesting(out);
}
private:
void BindInterface(mojo::GenericPendingReceiver receiver) {
if (!binder_map_.TryBind(&receiver)) {
if (!binder_map_with_context_.TryBind(internal::GetContextForHost(host_),
&receiver)) {
host_->ReportNoBinderForInterface("No binder found for interface " +
*receiver.interface_name());
}
}
}
const raw_ptr<ExecutionContextHost> host_;
mojo::BinderMap binder_map_;
mojo::BinderMapWithContext<InterfaceBinderContext> binder_map_with_context_;
// The lifetime of `policy_applier_` is managed by the owner of this instance.
// The owner should call `ReleaseMojoBinderPolicies()` when it destroys the
// applier.
raw_ptr<MojoBinderPolicyApplier> policy_applier_ = nullptr;
};
} // namespace content
#endif // CONTENT_BROWSER_BROWSER_INTERFACE_BROKER_IMPL_H_