Bug 1161507 - BroadcastChannel should use origin+appId+IsInBrowserElement as key in b2g, r=sicking

This commit is contained in:
Andrea Marchesini 2015-05-06 11:07:06 +01:00
parent 08b340a648
commit 168bebe33b
6 changed files with 42 additions and 79 deletions

View File

@ -16,10 +16,7 @@
#include "WorkerPrivate.h"
#include "WorkerRunnable.h"
#include "nsIAppsService.h"
#include "nsIDocument.h"
#include "nsIScriptSecurityManager.h"
#include "nsServiceManagerUtils.h"
#include "nsISupportsPrimitives.h"
#ifdef XP_WIN
@ -57,36 +54,6 @@ GetOrigin(nsIPrincipal* aPrincipal, nsAString& aOrigin, ErrorResult& aRv)
{
MOZ_ASSERT(aPrincipal);
bool unknownAppId;
aRv = aPrincipal->GetUnknownAppId(&unknownAppId);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
if (!unknownAppId) {
uint32_t appId;
aRv = aPrincipal->GetAppId(&appId);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
if (appId != nsIScriptSecurityManager::NO_APP_ID) {
// If we are in "app code", use manifest URL as unique origin since
// multiple apps can share the same origin but not same broadcast
// messages.
nsresult rv;
nsCOMPtr<nsIAppsService> appsService =
do_GetService("@mozilla.org/AppsService;1", &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return;
}
appsService->GetManifestURLByLocalId(appId, aOrigin);
return;
}
}
nsAutoString tmp;
aRv = nsContentUtils::GetUTFOrigin(aPrincipal, tmp);
if (NS_WARN_IF(aRv.Failed())) {

View File

@ -10,6 +10,7 @@
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/unused.h"
#include "nsIScriptSecurityManager.h"
namespace mozilla {
@ -18,16 +19,26 @@ using namespace ipc;
namespace dom {
BroadcastChannelParent::BroadcastChannelParent(
const PrincipalInfo& aPrincipalInfo,
const nsAString& aOrigin,
const nsAString& aChannel,
bool aPrivateBrowsing)
: mService(BroadcastChannelService::GetOrCreate())
, mOrigin(aOrigin)
, mChannel(aChannel)
, mAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID)
, mIsInBrowserElement(false)
, mPrivateBrowsing(aPrivateBrowsing)
{
AssertIsOnBackgroundThread();
mService->RegisterActor(this);
if (aPrincipalInfo.type() ==PrincipalInfo::TContentPrincipalInfo) {
const ContentPrincipalInfo& info =
aPrincipalInfo.get_ContentPrincipalInfo();
mAppId = info.appId();
mIsInBrowserElement = info.isInBrowserElement();
}
}
BroadcastChannelParent::~BroadcastChannelParent()
@ -44,7 +55,8 @@ BroadcastChannelParent::RecvPostMessage(const ClonedMessageData& aData)
return false;
}
mService->PostMessage(this, aData, mOrigin, mChannel, mPrivateBrowsing);
mService->PostMessage(this, aData, mOrigin, mAppId, mIsInBrowserElement,
mChannel, mPrivateBrowsing);
return true;
}
@ -80,12 +92,16 @@ BroadcastChannelParent::ActorDestroy(ActorDestroyReason aWhy)
void
BroadcastChannelParent::CheckAndDeliver(const ClonedMessageData& aData,
const nsString& aOrigin,
uint64_t aAppId,
bool aInBrowserElement,
const nsString& aChannel,
bool aPrivateBrowsing)
{
AssertIsOnBackgroundThread();
if (aOrigin == mOrigin &&
aAppId == mAppId &&
aInBrowserElement == mIsInBrowserElement &&
aChannel == mChannel &&
aPrivateBrowsing == mPrivateBrowsing) {
// We need to duplicate data only if we have blobs or if the manager of

View File

@ -13,6 +13,7 @@ namespace mozilla {
namespace ipc {
class BackgroundParentImpl;
class PrincipalInfo;
}
namespace dom {
@ -23,14 +24,19 @@ class BroadcastChannelParent final : public PBroadcastChannelParent
{
friend class mozilla::ipc::BackgroundParentImpl;
typedef mozilla::ipc::PrincipalInfo PrincipalInfo;
public:
void CheckAndDeliver(const ClonedMessageData& aData,
const nsString& aOrigin,
const uint64_t aAppId,
const bool aIsInBrowserElement,
const nsString& aChannel,
bool aPrivateBrowsing);
private:
BroadcastChannelParent(const nsAString& aOrigin,
BroadcastChannelParent(const PrincipalInfo& aPrincipalInfo,
const nsAString& aOrigin,
const nsAString& aChannel,
bool aPrivateBrowsing);
~BroadcastChannelParent();
@ -45,6 +51,8 @@ private:
nsRefPtr<BroadcastChannelService> mService;
nsString mOrigin;
nsString mChannel;
uint64_t mAppId;
bool mIsInBrowserElement;
bool mPrivateBrowsing;
};

View File

@ -84,12 +84,16 @@ struct MOZ_STACK_CLASS PostMessageData final
PostMessageData(BroadcastChannelParent* aParent,
const ClonedMessageData& aData,
const nsAString& aOrigin,
uint64_t aAppId,
bool aIsInBrowserElement,
const nsAString& aChannel,
bool aPrivateBrowsing)
: mParent(aParent)
, mData(aData)
, mOrigin(aOrigin)
, mChannel(aChannel)
, mAppId(aAppId)
, mIsInBrowserElement(aIsInBrowserElement)
, mPrivateBrowsing(aPrivateBrowsing)
{
MOZ_ASSERT(aParent);
@ -119,6 +123,8 @@ struct MOZ_STACK_CLASS PostMessageData final
nsTArray<nsRefPtr<FileImpl>> mFiles;
const nsString mOrigin;
const nsString mChannel;
uint64_t mAppId;
bool mIsInBrowserElement;
bool mPrivateBrowsing;
};
@ -132,7 +138,8 @@ PostMessageEnumerator(nsPtrHashKey<BroadcastChannelParent>* aKey, void* aPtr)
MOZ_ASSERT(parent);
if (parent != data->mParent) {
parent->CheckAndDeliver(data->mData, data->mOrigin, data->mChannel,
parent->CheckAndDeliver(data->mData, data->mOrigin, data->mAppId,
data->mIsInBrowserElement, data->mChannel,
data->mPrivateBrowsing);
}
@ -145,6 +152,8 @@ void
BroadcastChannelService::PostMessage(BroadcastChannelParent* aParent,
const ClonedMessageData& aData,
const nsAString& aOrigin,
uint64_t aAppId,
bool aIsInBrowserElement,
const nsAString& aChannel,
bool aPrivateBrowsing)
{
@ -152,7 +161,8 @@ BroadcastChannelService::PostMessage(BroadcastChannelParent* aParent,
MOZ_ASSERT(aParent);
MOZ_ASSERT(mAgents.Contains(aParent));
PostMessageData data(aParent, aData, aOrigin, aChannel, aPrivateBrowsing);
PostMessageData data(aParent, aData, aOrigin, aAppId, aIsInBrowserElement,
aChannel, aPrivateBrowsing);
mAgents.EnumerateEntries(PostMessageEnumerator, &data);
}

View File

@ -34,6 +34,8 @@ public:
void PostMessage(BroadcastChannelParent* aParent,
const ClonedMessageData& aData,
const nsAString& aOrigin,
uint64_t aAppId,
bool aIsInBrowserElement,
const nsAString& aChannel,
bool aPrivateBrowsing);

View File

@ -262,7 +262,8 @@ BackgroundParentImpl::AllocPBroadcastChannelParent(
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
return new BroadcastChannelParent(aOrigin, aChannel, aPrivateBrowsing);
return new BroadcastChannelParent(aPrincipalInfo, aOrigin, aChannel,
aPrivateBrowsing);
}
namespace {
@ -315,47 +316,6 @@ public:
return NS_OK;
}
bool unknownAppId;
rv = principal->GetUnknownAppId(&unknownAppId);
if (NS_WARN_IF(NS_FAILED(rv))) {
mContentParent->KillHard("BroadcastChannel killed: failed to get the app status.");
return NS_OK;
}
if (!unknownAppId) {
uint32_t appId;
rv = principal->GetAppId(&appId);
if (NS_WARN_IF(NS_FAILED(rv))) {
mContentParent->KillHard("BroadcastChannel killed: failed to get the app id.");
return NS_OK;
}
// If the broadcastChannel is used by an app, the origin is the manifest URL.
if (appId != nsIScriptSecurityManager::NO_APP_ID) {
nsresult rv;
nsCOMPtr<nsIAppsService> appsService =
do_GetService("@mozilla.org/AppsService;1", &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
mContentParent->KillHard("BroadcastChannel killed: appService getter failed.");
return NS_OK;
}
nsAutoString origin;
rv = appsService->GetManifestURLByLocalId(appId, origin);
if (NS_WARN_IF(NS_FAILED(rv))) {
mContentParent->KillHard("BroadcastChannel killed: failed to retrieve the manifestURL.");
return NS_OK;
}
if (!origin.Equals(mOrigin)) {
mContentParent->KillHard("BroadcastChannel killed: origins do not match.");
return NS_OK;
}
return NS_OK;
}
}
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), mOrigin);
if (NS_FAILED(rv) || !uri) {