Bug 1605176 - Send a error message data and cause a message error on the receiver side when the message data contains a shared memory object in BrowsingContext::PostMessageMoz; r=baku,kmag

Differential Revision: https://phabricator.services.mozilla.com/D75035
This commit is contained in:
Tom Tung 2020-05-20 08:27:16 +00:00
parent 5485075de6
commit d9d34b2983
10 changed files with 94 additions and 20 deletions

View File

@ -1732,24 +1732,71 @@ void BrowsingContext::PostMessageMoz(JSContext* aCx,
return;
}
ipc::StructuredCloneData message;
message.Write(aCx, aMessage, transferArray, JS::CloneDataPolicy(), aError);
JS::CloneDataPolicy clonePolicy;
if (callerInnerWindow && callerInnerWindow->IsSharedMemoryAllowed()) {
clonePolicy.allowSharedMemoryObjects();
}
// We will see if the message is required to be in the same process or it can
// be in the different process after Write().
ipc::StructuredCloneData message = ipc::StructuredCloneData(
StructuredCloneHolder::StructuredCloneScope::UnknownDestination,
StructuredCloneHolder::TransferringSupported);
message.Write(aCx, aMessage, transferArray, clonePolicy, aError);
if (NS_WARN_IF(aError.Failed())) {
return;
}
ClonedMessageData messageData;
ClonedOrErrorMessageData messageData;
if (ContentChild* cc = ContentChild::GetSingleton()) {
if (!message.BuildClonedMessageDataForChild(cc, messageData)) {
aError.Throw(NS_ERROR_FAILURE);
return;
// The clone scope gets set when we write the message data based on the
// requirements of that data that we're writing.
// If the message data contins a shared memory object, then CloneScope would
// return SameProcess. Otherwise, it returns DifferentProcess.
if (message.CloneScope() ==
StructuredCloneHolder::StructuredCloneScope::DifferentProcess) {
ClonedMessageData clonedMessageData;
if (!message.BuildClonedMessageDataForChild(cc, clonedMessageData)) {
aError.Throw(NS_ERROR_FAILURE);
return;
}
messageData = std::move(clonedMessageData);
} else {
MOZ_ASSERT(message.CloneScope() ==
StructuredCloneHolder::StructuredCloneScope::SameProcess);
messageData = ErrorMessageData();
nsContentUtils::ReportToConsole(
nsIScriptError::warningFlag, NS_LITERAL_CSTRING("DOM Window"),
callerInnerWindow ? callerInnerWindow->GetDocument() : nullptr,
nsContentUtils::eDOM_PROPERTIES,
"PostMessageSharedMemoryObjectToCrossOriginWarning");
}
cc->SendWindowPostMessage(this, messageData, data);
} else if (ContentParent* cp = Canonical()->GetContentParent()) {
if (!message.BuildClonedMessageDataForParent(cp, messageData)) {
aError.Throw(NS_ERROR_FAILURE);
return;
if (message.CloneScope() ==
StructuredCloneHolder::StructuredCloneScope::DifferentProcess) {
ClonedMessageData clonedMessageData;
if (!message.BuildClonedMessageDataForParent(cp, clonedMessageData)) {
aError.Throw(NS_ERROR_FAILURE);
return;
}
messageData = std::move(clonedMessageData);
} else {
MOZ_ASSERT(message.CloneScope() ==
StructuredCloneHolder::StructuredCloneScope::SameProcess);
messageData = ErrorMessageData();
nsContentUtils::ReportToConsole(
nsIScriptError::warningFlag, NS_LITERAL_CSTRING("DOM Window"),
callerInnerWindow ? callerInnerWindow->GetDocument() : nullptr,
nsContentUtils::eDOM_PROPERTIES,
"PostMessageSharedMemoryObjectToCrossOriginWarning");
}
Unused << cp->SendWindowPostMessage(this, messageData, data);

View File

@ -183,6 +183,11 @@ PostMessageEvent::Run() {
cloneDataPolicy.allowSharedMemoryObjects();
}
if (mHolder.empty()) {
DispatchError(cx, targetWindow, eventTarget);
return NS_OK;
}
StructuredCloneHolder* holder;
if (mHolder.constructed<StructuredCloneHolder>()) {
mHolder.ref<StructuredCloneHolder>().Read(

View File

@ -64,7 +64,11 @@ class PostMessageEvent final : public Runnable {
mHolder.ref<StructuredCloneHolder>().Write(aCx, aMessage, aTransfer,
aClonePolicy, aError);
}
void UnpackFrom(const ClonedMessageData& aMessageData) {
void UnpackFrom(const ClonedOrErrorMessageData& aMessageData) {
if (aMessageData.type() != ClonedOrErrorMessageData::TClonedMessageData) {
return;
}
mHolder.construct<ipc::StructuredCloneData>();
// FIXME Want to steal!
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1516349.

View File

@ -3979,7 +3979,7 @@ mozilla::ipc::IPCResult ContentChild::RecvMaybeExitFullscreen(
mozilla::ipc::IPCResult ContentChild::RecvWindowPostMessage(
const MaybeDiscarded<BrowsingContext>& aContext,
const ClonedMessageData& aMessage, const PostMessageData& aData) {
const ClonedOrErrorMessageData& aMessage, const PostMessageData& aData) {
if (aContext.IsNullOrDiscarded()) {
MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
("ChildIPC: Trying to send a message to dead or detached context"));

View File

@ -765,7 +765,7 @@ class ContentChild final : public PContentChild,
mozilla::ipc::IPCResult RecvWindowPostMessage(
const MaybeDiscarded<BrowsingContext>& aContext,
const ClonedMessageData& aMessage, const PostMessageData& aData);
const ClonedOrErrorMessageData& aMessage, const PostMessageData& aData);
mozilla::ipc::IPCResult RecvCommitBrowsingContextTransaction(
const MaybeDiscarded<BrowsingContext>& aContext,

View File

@ -6318,7 +6318,7 @@ mozilla::ipc::IPCResult ContentParent::RecvMaybeExitFullscreen(
mozilla::ipc::IPCResult ContentParent::RecvWindowPostMessage(
const MaybeDiscarded<BrowsingContext>& aContext,
const ClonedMessageData& aMessage, const PostMessageData& aData) {
const ClonedOrErrorMessageData& aMessage, const PostMessageData& aData) {
if (aContext.IsNullOrDiscarded()) {
MOZ_LOG(
BrowsingContext::GetLog(), LogLevel::Debug,
@ -6341,13 +6341,22 @@ mozilla::ipc::IPCResult ContentParent::RecvWindowPostMessage(
return IPC_OK();
}
ClonedOrErrorMessageData message;
StructuredCloneData messageFromChild;
UnpackClonedMessageDataForParent(aMessage, messageFromChild);
if (aMessage.type() == ClonedOrErrorMessageData::TClonedMessageData) {
UnpackClonedMessageDataForParent(aMessage, messageFromChild);
ClonedMessageData message;
if (!BuildClonedMessageDataForParent(cp, messageFromChild, message)) {
// FIXME Logging?
return IPC_OK();
ClonedMessageData clonedMessageData;
if (BuildClonedMessageDataForParent(cp, messageFromChild,
clonedMessageData)) {
message = std::move(clonedMessageData);
} else {
// FIXME Logging?
message = ErrorMessageData();
}
} else {
MOZ_ASSERT(aMessage.type() == ClonedOrErrorMessageData::TErrorMessageData);
message = ErrorMessageData();
}
Unused << cp->SendWindowPostMessage(context, message, aData);

View File

@ -683,7 +683,7 @@ class ContentParent final
mozilla::ipc::IPCResult RecvWindowPostMessage(
const MaybeDiscarded<BrowsingContext>& aContext,
const ClonedMessageData& aMessage, const PostMessageData& aData);
const ClonedOrErrorMessageData& aMessage, const PostMessageData& aData);
FORWARD_SHMEM_ALLOCATOR_TO(PContentParent)

View File

@ -71,6 +71,14 @@ struct ClonedMessageData
MessagePortIdentifier[] identifiers;
};
struct ErrorMessageData {
};
union ClonedOrErrorMessageData {
ClonedMessageData;
ErrorMessageData;
};
struct RefMessageData {
nsID uuid;
};

View File

@ -1678,7 +1678,7 @@ child:
both:
async MaybeExitFullscreen(MaybeDiscardedBrowsingContext aContext);
async WindowPostMessage(MaybeDiscardedBrowsingContext aContext,
ClonedMessageData aMessage,
ClonedOrErrorMessageData aMessage,
PostMessageData aData);
/**

View File

@ -393,3 +393,4 @@ WebShareAPI_Failed=The share operation has failed.
WebShareAPI_Aborted=The share operation was aborted.
# LOCALIZATION NOTE (UnknownProtocolNavigationPrevented): %1$S is the destination URL.
UnknownProtocolNavigationPrevented=Prevented navigation to “%1$S” due to an unknown protocol.
PostMessageSharedMemoryObjectToCrossOriginWarning=Cannot post message containing a shared memory object to a cross-origin window.