Commit 7a94d28c authored by Dave Tapuska's avatar Dave Tapuska Committed by Commit Bot

Add use counters to track shared array buffer passing.

Add 3 use counters to track the following usages
1) Different Agent Clusters
2) Same Agent Clusters
3) Same Origin

Adds counters for https://github.com/whatwg/html/issues/4920

Change-Id: Ia9aeb1afb1f355790c5dfb549f1e2459d95d98ef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1925218
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
Reviewed-by: default avatarMarijn Kruisselbrink <mek@chromium.org>
Reviewed-by: default avatarJeremy Roman <jbroman@chromium.org>
Reviewed-by: default avatarBen Kelly <wanderview@chromium.org>
Cr-Commit-Position: refs/heads/master@{#719379}
parent 594fd745
......@@ -2482,6 +2482,9 @@ enum WebFeature {
kV8PortalActivateEvent_Data_AttributeGetter = 3101,
kV8PortalActivateEvent_AdoptPredecessor_Method = 3102,
kLinkRelPrefetchForSignedExchanges = 3103,
kMessageEventSharedArrayBufferSameOrigin = 3104,
kMessageEventSharedArrayBufferSameAgentCluster = 3105,
kMessageEventSharedArrayBufferDifferentAgentCluster = 3106,
// Add new features immediately above this line. Don't change assigned
// numbers of any item, and don't reuse removed slots.
......
......@@ -30,6 +30,8 @@
#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_DOM_MESSAGE_EVENT_H_
#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_DOM_MESSAGE_EVENT_H_
#include "base/optional.h"
#include "base/unguessable_token.h"
#include "third_party/blink/public/common/messaging/message_port_channel.h"
#include "third_party/blink/public/common/messaging/transferable_message.h"
#include "third_party/blink/public/platform/web_string.h"
......@@ -65,6 +67,10 @@ class WebDOMMessageEvent : public WebDOMEvent {
BLINK_EXPORT WebString Origin() const;
base::Optional<base::UnguessableToken> locked_agent_cluster_id() const {
return locked_agent_cluster_id_;
}
// The |encoded_message| in the returned message is only valid as long as this
// WebDOMMessageEvent is still valid, unless EnsureDataIsOwned is called on
// the returned message.
......@@ -73,6 +79,9 @@ class WebDOMMessageEvent : public WebDOMEvent {
#if INSIDE_BLINK
explicit WebDOMMessageEvent(MessageEvent* e) : WebDOMEvent(e) {}
#endif
private:
base::Optional<base::UnguessableToken> locked_agent_cluster_id_;
};
} // namespace blink
......
......@@ -328,6 +328,13 @@ bool MessageEvent::IsOriginCheckRequiredToAccessData() const {
return data_as_serialized_script_value_->Value()->IsOriginCheckRequired();
}
bool MessageEvent::IsLockedToAgentCluster() const {
if (data_type_ != kDataTypeSerializedScriptValue) {
return false;
}
return data_as_serialized_script_value_->Value()->IsLockedToAgentCluster();
}
void MessageEvent::EntangleMessagePorts(ExecutionContext* context) {
ports_ = MessagePort::EntanglePorts(*context, std::move(channels_));
is_ports_dirty_ = true;
......
......@@ -187,6 +187,10 @@ class CORE_EXPORT MessageEvent final : public Event {
// messageerror event instead of message event.
bool IsOriginCheckRequiredToAccessData() const;
// Returns true when |data_as_serialized_script_value_| is locked to an
// agent cluster.
bool IsLockedToAgentCluster() const;
void EntangleMessagePorts(ExecutionContext*);
void Trace(blink::Visitor*) override;
......
......@@ -74,6 +74,7 @@ WebDOMMessageEvent::WebDOMMessageEvent(TransferableMessage message,
DOMWindow* window = nullptr;
if (source_frame)
window = WebFrame::ToCoreFrame(*source_frame)->DomWindow();
locked_agent_cluster_id_ = message.locked_agent_cluster_id;
BlinkTransferableMessage msg = ToBlinkTransferableMessage(std::move(message));
MessagePortArray* ports = nullptr;
if (!target_document.IsNull()) {
......
......@@ -561,17 +561,19 @@ void LocalDOMWindow::SchedulePostMessage(
// surfaces often as a problem (see crbug.com/587012).
std::unique_ptr<SourceLocation> location = SourceLocation::Capture(source);
document_->GetTaskRunner(TaskType::kPostedMessage)
->PostTask(FROM_HERE,
WTF::Bind(&LocalDOMWindow::DispatchPostMessage,
WrapPersistent(this), WrapPersistent(event),
std::move(target), std::move(location)));
->PostTask(
FROM_HERE,
WTF::Bind(&LocalDOMWindow::DispatchPostMessage, WrapPersistent(this),
WrapPersistent(event), std::move(target),
std::move(location), source->GetAgentClusterID()));
probe::AsyncTaskScheduled(document(), "postMessage", event->async_task_id());
}
void LocalDOMWindow::DispatchPostMessage(
MessageEvent* event,
scoped_refptr<const SecurityOrigin> intended_target_origin,
std::unique_ptr<SourceLocation> location) {
std::unique_ptr<SourceLocation> location,
const base::UnguessableToken& source_agent_cluster_id) {
probe::AsyncTask async_task(document(), event->async_task_id());
if (!IsCurrentlyDisplayedInFrame())
return;
......@@ -579,13 +581,15 @@ void LocalDOMWindow::DispatchPostMessage(
event->EntangleMessagePorts(document());
DispatchMessageEventWithOriginCheck(intended_target_origin.get(), event,
std::move(location));
std::move(location),
source_agent_cluster_id);
}
void LocalDOMWindow::DispatchMessageEventWithOriginCheck(
const SecurityOrigin* intended_target_origin,
MessageEvent* event,
std::unique_ptr<SourceLocation> location) {
std::unique_ptr<SourceLocation> location,
const base::UnguessableToken& source_agent_cluster_id) {
if (intended_target_origin) {
// Check target origin now since the target document may have changed since
// the timer was scheduled.
......@@ -626,6 +630,28 @@ void LocalDOMWindow::DispatchMessageEventWithOriginCheck(
event = MessageEvent::CreateError(event->origin(), event->source());
}
}
if (event->IsLockedToAgentCluster()) {
if (!document()->IsSameAgentCluster(source_agent_cluster_id)) {
UseCounter::Count(
document(),
WebFeature::kMessageEventSharedArrayBufferDifferentAgentCluster);
// TODO(dtapuska): Make sure this generates an error. See
// https://crbug.com/1028736
// event = MessageEvent::CreateError(event->origin(), event->source());
} else {
scoped_refptr<SecurityOrigin> sender_origin =
SecurityOrigin::Create(sender);
if (!sender_origin->IsSameSchemeHostPort(
document()->GetSecurityOrigin())) {
UseCounter::Count(
document(),
WebFeature::kMessageEventSharedArrayBufferSameAgentCluster);
} else {
UseCounter::Count(document(),
WebFeature::kMessageEventSharedArrayBufferSameOrigin);
}
}
}
DispatchEvent(*event);
}
......
......@@ -276,12 +276,14 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
void DispatchPostMessage(
MessageEvent* event,
scoped_refptr<const SecurityOrigin> intended_target_origin,
std::unique_ptr<SourceLocation> location);
std::unique_ptr<SourceLocation> location,
const base::UnguessableToken& source_agent_cluster_id);
void DispatchMessageEventWithOriginCheck(
const SecurityOrigin* intended_target_origin,
MessageEvent*,
std::unique_ptr<SourceLocation>);
std::unique_ptr<SourceLocation>,
const base::UnguessableToken& source_agent_cluster_id);
// Events
// EventTarget API
......
......@@ -2333,7 +2333,9 @@ void WebLocalFrameImpl::DispatchMessageEventWithOriginCheck(
GetFrame()->DomWindow()->DispatchMessageEventWithOriginCheck(
intended_target_origin.Get(), msg_event,
std::make_unique<SourceLocation>(String(), 0, 0, nullptr));
std::make_unique<SourceLocation>(String(), 0, 0, nullptr),
event.locked_agent_cluster_id() ? event.locked_agent_cluster_id().value()
: base::UnguessableToken());
}
WebNode WebLocalFrameImpl::ContextMenuNode() const {
......
......@@ -307,21 +307,33 @@ bool MessagePort::Accept(mojo::Message* mojo_message) {
}
Event* MessagePort::CreateMessageEvent(BlinkTransferableMessage& message) {
ExecutionContext* context = GetExecutionContext();
// Dispatch a messageerror event when the target is a remote origin that is
// not allowed to access the message's data.
if (message.message->IsOriginCheckRequired()) {
const SecurityOrigin* target_origin =
GetExecutionContext()->GetSecurityOrigin();
const SecurityOrigin* target_origin = context->GetSecurityOrigin();
if (!message.sender_origin ||
!message.sender_origin->IsSameSchemeHostPort(target_origin)) {
return MessageEvent::CreateError();
}
}
if (message.locked_agent_cluster_id &&
!GetExecutionContext()->IsSameAgentCluster(
*message.locked_agent_cluster_id)) {
return MessageEvent::CreateError();
if (message.locked_agent_cluster_id) {
if (!context->IsSameAgentCluster(*message.locked_agent_cluster_id)) {
UseCounter::Count(
context,
WebFeature::kMessageEventSharedArrayBufferDifferentAgentCluster);
return MessageEvent::CreateError();
}
const SecurityOrigin* target_origin = context->GetSecurityOrigin();
if (!message.sender_origin ||
!message.sender_origin->IsSameSchemeHostPort(target_origin)) {
UseCounter::Count(
context, WebFeature::kMessageEventSharedArrayBufferSameAgentCluster);
} else {
UseCounter::Count(context,
WebFeature::kMessageEventSharedArrayBufferSameOrigin);
}
}
MessagePortArray* ports = MessagePort::EntanglePorts(
......
......@@ -25591,6 +25591,9 @@ Called by update_net_error_codes.py.-->
<int value="3101" label="V8PortalActivateEvent_Data_AttributeGetter"/>
<int value="3102" label="V8PortalActivateEvent_AdoptPredecessor_Method"/>
<int value="3103" label="LinkRelPrefetchForSignedExchanges"/>
<int value="3104" label="MessageEventSharedArrayBufferSameOrigin"/>
<int value="3105" label="MessageEventSharedArrayBufferSameAgentCluster"/>
<int value="3106" label="MessageEventSharedArrayBufferDifferentAgentCluster"/>
</enum>
<enum name="FeaturePolicyAllowlistType">
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