Bug 1658878 - Isolate BlobURLs per agent-cluster, r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D86914
This commit is contained in:
Andrea Marchesini 2020-08-14 16:59:44 +00:00
parent e462454933
commit 91ce718928
10 changed files with 176 additions and 129 deletions

View File

@ -363,47 +363,25 @@ void BlobURLInputStream::RetrieveBlobData(const MutexAutoLock& aProofOfLock) {
return;
}
Maybe<nsID> agentClusterId;
Maybe<ClientInfo> clientInfo = loadInfo->GetClientInfo();
if (clientInfo.isSome()) {
agentClusterId = clientInfo->AgentClusterId();
}
if (XRE_IsParentProcess() || !BlobURLSchemeIsHTTPOrHTTPS(mBlobURLSpec)) {
nsIPrincipal* const dataEntryPrincipal =
BlobURLProtocolHandler::GetDataEntryPrincipal(mBlobURLSpec,
true /* AlsoIfRevoked */);
RefPtr<BlobImpl> blobImpl;
// Since revoked blobs are also retrieved, it is possible that the blob no
// longer exists (due to the 5 second timeout) when execution reaches here
if (!dataEntryPrincipal) {
if (!BlobURLProtocolHandler::GetDataEntry(
mBlobURLSpec, getter_AddRefs(blobImpl), loadingPrincipal,
triggeringPrincipal, loadInfo->GetOriginAttributes(),
agentClusterId, true /* AlsoIfRevoked */)) {
NS_WARNING("Failed to get data entry principal. URL revoked?");
return;
}
// We want to be sure that we stop the creation of the channel if the blob
// URL is copy-and-pasted on a different context (ex. private browsing or
// containers).
//
// We also allow the system principal to create the channel regardless of
// the OriginAttributes. This is primarily for the benefit of mechanisms
// like the Download API that explicitly create a channel with the system
// principal and which is never mutated to have a non-zero
// mPrivateBrowsingId or container.
if (NS_WARN_IF(!loadingPrincipal ||
!loadingPrincipal->IsSystemPrincipal()) &&
NS_WARN_IF(!ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
loadInfo->GetOriginAttributes(),
BasePrincipal::Cast(dataEntryPrincipal)->OriginAttributesRef()))) {
return;
}
if (NS_WARN_IF(!triggeringPrincipal->Subsumes(dataEntryPrincipal))) {
return;
}
RefPtr<BlobImpl> blobImpl;
nsresult rv = NS_GetBlobForBlobURISpec(
mBlobURLSpec, getter_AddRefs(blobImpl), true /* AlsoIfRevoked */);
if (NS_WARN_IF(NS_FAILED(rv)) || (NS_WARN_IF(!blobImpl))) {
return;
}
if (NS_WARN_IF(
NS_FAILED(StoreBlobImplStream(blobImpl.forget(), aProofOfLock)))) {
return;
@ -431,7 +409,7 @@ void BlobURLInputStream::RetrieveBlobData(const MutexAutoLock& aProofOfLock) {
contentChild
->SendBlobURLDataRequest(mBlobURLSpec, triggeringPrincipal,
loadingPrincipal,
loadInfo->GetOriginAttributes())
loadInfo->GetOriginAttributes(), agentClusterId)
->Then(
GetCurrentSerialEventTarget(), __func__,
[self](const BlobURLDataRequestResult& aResult) {

View File

@ -19,6 +19,7 @@
#include "mozilla/BasePrincipal.h"
#include "mozilla/LoadInfo.h"
#include "mozilla/NullPrincipal.h"
#include "mozilla/OriginAttributes.h"
#include "mozilla/Preferences.h"
#include "mozilla/SchedulerGroup.h"
#include "nsClassHashtable.h"
@ -45,18 +46,22 @@ namespace dom {
struct DataInfo {
enum ObjectType { eBlobImpl, eMediaSource };
DataInfo(BlobImpl* aBlobImpl, nsIPrincipal* aPrincipal)
DataInfo(BlobImpl* aBlobImpl, nsIPrincipal* aPrincipal,
const Maybe<nsID>& aAgentClusterId)
: mObjectType(eBlobImpl),
mBlobImpl(aBlobImpl),
mPrincipal(aPrincipal),
mAgentClusterId(aAgentClusterId),
mRevoked(false) {
MOZ_ASSERT(aPrincipal);
}
DataInfo(MediaSource* aMediaSource, nsIPrincipal* aPrincipal)
DataInfo(MediaSource* aMediaSource, nsIPrincipal* aPrincipal,
const Maybe<nsID>& aAgentClusterId)
: mObjectType(eMediaSource),
mMediaSource(aMediaSource),
mPrincipal(aPrincipal),
mAgentClusterId(aAgentClusterId),
mRevoked(false) {
MOZ_ASSERT(aPrincipal);
}
@ -67,6 +72,8 @@ struct DataInfo {
RefPtr<MediaSource> mMediaSource;
nsCOMPtr<nsIPrincipal> mPrincipal;
Maybe<nsID> mAgentClusterId;
nsCString mStack;
// When a blobURL is revoked, we keep it alive for RELEASING_TIMER
@ -124,14 +131,15 @@ static DataInfo* GetDataInfoFromURI(nsIURI* aURI, bool aAlsoIfRevoked = false) {
// Memory reporting for the hash table.
void BroadcastBlobURLRegistration(const nsACString& aURI, BlobImpl* aBlobImpl,
nsIPrincipal* aPrincipal) {
nsIPrincipal* aPrincipal,
const Maybe<nsID>& aAgentClusterId) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aBlobImpl);
MOZ_ASSERT(aPrincipal);
if (XRE_IsParentProcess()) {
dom::ContentParent::BroadcastBlobURLRegistration(aURI, aBlobImpl,
aPrincipal);
dom::ContentParent::BroadcastBlobURLRegistration(
aURI, aBlobImpl, aPrincipal, aAgentClusterId);
return;
}
@ -144,7 +152,7 @@ void BroadcastBlobURLRegistration(const nsACString& aURI, BlobImpl* aBlobImpl,
}
Unused << NS_WARN_IF(!cc->SendStoreAndBroadcastBlobURLRegistration(
nsCString(aURI), ipcBlob, IPC::Principal(aPrincipal)));
nsCString(aURI), ipcBlob, IPC::Principal(aPrincipal), aAgentClusterId));
}
void BroadcastBlobURLUnregistration(const nsCString& aURI,
@ -510,14 +518,15 @@ NS_IMPL_ISUPPORTS_INHERITED(ReleasingTimerHolder, Runnable, nsITimerCallback,
template <typename T>
static void AddDataEntryInternal(const nsACString& aURI, T aObject,
nsIPrincipal* aPrincipal) {
nsIPrincipal* aPrincipal,
const Maybe<nsID>& aAgentClusterId) {
MOZ_ASSERT(NS_IsMainThread(), "changing gDataTable is main-thread only");
StaticMutexAutoLock lock(sMutex);
if (!gDataTable) {
gDataTable = new nsClassHashtable<nsCStringHashKey, DataInfo>;
}
DataInfo* info = new DataInfo(aObject, aPrincipal);
DataInfo* info = new DataInfo(aObject, aPrincipal, aAgentClusterId);
BlobURLsReporter::GetJSStackForBlob(info);
gDataTable->Put(aURI, info);
@ -537,9 +546,9 @@ BlobURLProtocolHandler::BlobURLProtocolHandler() { Init(); }
BlobURLProtocolHandler::~BlobURLProtocolHandler() = default;
/* static */
nsresult BlobURLProtocolHandler::AddDataEntry(BlobImpl* aBlobImpl,
nsIPrincipal* aPrincipal,
nsACString& aUri) {
nsresult BlobURLProtocolHandler::AddDataEntry(
BlobImpl* aBlobImpl, nsIPrincipal* aPrincipal,
const Maybe<nsID>& aAgentClusterId, nsACString& aUri) {
MOZ_ASSERT(aBlobImpl);
MOZ_ASSERT(aPrincipal);
@ -548,16 +557,16 @@ nsresult BlobURLProtocolHandler::AddDataEntry(BlobImpl* aBlobImpl,
nsresult rv = GenerateURIString(aPrincipal, aUri);
NS_ENSURE_SUCCESS(rv, rv);
AddDataEntryInternal(aUri, aBlobImpl, aPrincipal);
AddDataEntryInternal(aUri, aBlobImpl, aPrincipal, aAgentClusterId);
BroadcastBlobURLRegistration(aUri, aBlobImpl, aPrincipal);
BroadcastBlobURLRegistration(aUri, aBlobImpl, aPrincipal, aAgentClusterId);
return NS_OK;
}
/* static */
nsresult BlobURLProtocolHandler::AddDataEntry(MediaSource* aMediaSource,
nsIPrincipal* aPrincipal,
nsACString& aUri) {
nsresult BlobURLProtocolHandler::AddDataEntry(
MediaSource* aMediaSource, nsIPrincipal* aPrincipal,
const Maybe<nsID>& aAgentClusterId, nsACString& aUri) {
MOZ_ASSERT(aMediaSource);
MOZ_ASSERT(aPrincipal);
@ -566,23 +575,24 @@ nsresult BlobURLProtocolHandler::AddDataEntry(MediaSource* aMediaSource,
nsresult rv = GenerateURIString(aPrincipal, aUri);
NS_ENSURE_SUCCESS(rv, rv);
AddDataEntryInternal(aUri, aMediaSource, aPrincipal);
AddDataEntryInternal(aUri, aMediaSource, aPrincipal, aAgentClusterId);
return NS_OK;
}
/* static */
void BlobURLProtocolHandler::AddDataEntry(const nsACString& aURI,
nsIPrincipal* aPrincipal,
const Maybe<nsID>& aAgentClusterId,
BlobImpl* aBlobImpl) {
MOZ_ASSERT(aPrincipal);
MOZ_ASSERT(aBlobImpl);
AddDataEntryInternal(aURI, aBlobImpl, aPrincipal);
AddDataEntryInternal(aURI, aBlobImpl, aPrincipal, aAgentClusterId);
}
/* static */
bool BlobURLProtocolHandler::ForEachBlobURL(
std::function<bool(BlobImpl*, nsIPrincipal*, const nsACString&,
bool aRevoked)>&& aCb) {
std::function<bool(BlobImpl*, nsIPrincipal*, const Maybe<nsID>&,
const nsACString&, bool aRevoked)>&& aCb) {
MOZ_ASSERT(NS_IsMainThread());
if (!gDataTable) {
@ -598,7 +608,8 @@ bool BlobURLProtocolHandler::ForEachBlobURL(
}
MOZ_ASSERT(info->mBlobImpl);
if (!aCb(info->mBlobImpl, info->mPrincipal, iter.Key(), info->mRevoked)) {
if (!aCb(info->mBlobImpl, info->mPrincipal, info->mAgentClusterId,
iter.Key(), info->mRevoked)) {
return false;
}
}
@ -687,6 +698,59 @@ nsresult BlobURLProtocolHandler::GenerateURIString(nsIPrincipal* aPrincipal,
return NS_OK;
}
/* static */
bool BlobURLProtocolHandler::GetDataEntry(
const nsACString& aUri, BlobImpl** aBlobImpl,
nsIPrincipal* aLoadingPrincipal, nsIPrincipal* aTriggeringPrincipal,
const OriginAttributes& aOriginAttributes,
const Maybe<nsID>& aAgentClusterId, bool aAlsoIfRevoked) {
MOZ_ASSERT(NS_IsMainThread(),
"without locking gDataTable is main-thread only");
MOZ_ASSERT(aTriggeringPrincipal);
if (!gDataTable) {
return false;
}
DataInfo* info = GetDataInfo(aUri, aAlsoIfRevoked);
if (!info) {
return false;
}
// We want to be sure that we stop the creation of the channel if the blob
// URL is copy-and-pasted on a different context (ex. private browsing or
// containers).
//
// We also allow the system principal to create the channel regardless of
// the OriginAttributes. This is primarily for the benefit of mechanisms
// like the Download API that explicitly create a channel with the system
// principal and which is never mutated to have a non-zero
// mPrivateBrowsingId or container.
if (NS_WARN_IF(!aLoadingPrincipal ||
!aLoadingPrincipal->IsSystemPrincipal()) &&
NS_WARN_IF(!ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
aOriginAttributes,
BasePrincipal::Cast(info->mPrincipal)->OriginAttributesRef()))) {
return false;
}
if (!aTriggeringPrincipal->Subsumes(info->mPrincipal)) {
return false;
}
// Same agent-cluster only.
if (aAgentClusterId.isSome() && info->mAgentClusterId.isSome() &&
!aAgentClusterId.value().Equals(info->mAgentClusterId.value())) {
return false;
}
RefPtr<BlobImpl> blobImpl = info->mBlobImpl;
blobImpl.forget(aBlobImpl);
return true;
}
/* static */
nsIPrincipal* BlobURLProtocolHandler::GetDataEntryPrincipal(
const nsACString& aUri, bool aAlsoIfRevoked) {

View File

@ -21,6 +21,7 @@ class nsIPrincipal;
namespace mozilla {
class BlobURLsReporter;
class OriginAttributes;
namespace dom {
@ -44,10 +45,16 @@ class BlobURLProtocolHandler final : public nsIProtocolHandler,
// Methods for managing uri->object mapping
// AddDataEntry creates the URI with the given scheme and returns it in aUri
static nsresult AddDataEntry(BlobImpl*, nsIPrincipal*, nsACString& aUri);
static nsresult AddDataEntry(MediaSource*, nsIPrincipal*, nsACString& aUri);
static nsresult AddDataEntry(BlobImpl*, nsIPrincipal*,
const Maybe<nsID>& aAgentClusterId,
nsACString& aUri);
static nsresult AddDataEntry(MediaSource*, nsIPrincipal*,
const Maybe<nsID>& aAgentClusterId,
nsACString& aUri);
// IPC only
static void AddDataEntry(const nsACString& aURI, nsIPrincipal*, BlobImpl*);
static void AddDataEntry(const nsACString& aURI, nsIPrincipal* aPrincipal,
const Maybe<nsID>& aAgentClusterId,
BlobImpl* aBlobImpl);
// This method revokes a blobURL. Because some operations could still be in
// progress, the revoking consists in marking the blobURL as revoked and in
@ -59,6 +66,13 @@ class BlobURLProtocolHandler final : public nsIProtocolHandler,
static bool HasDataEntry(const nsACString& aUri);
static bool GetDataEntry(const nsACString& aUri, BlobImpl** aBlobImpl,
nsIPrincipal* aLoadingPrincipal,
nsIPrincipal* aTriggeringPrincipal,
const OriginAttributes& aOriginAttributes,
const Maybe<nsID>& blobAgentClusterId,
bool aAlsoIfRevoked = false);
static nsIPrincipal* GetDataEntryPrincipal(const nsACString& aUri,
bool aAlsoIfRevoked = false);
static void Traverse(const nsACString& aUri,
@ -70,8 +84,8 @@ class BlobURLProtocolHandler final : public nsIProtocolHandler,
// of an unexpected XPCOM or IPC error). This method returns false if already
// shutdown or if the helper method returns false, true otherwise.
static bool ForEachBlobURL(
std::function<bool(BlobImpl*, nsIPrincipal*, const nsACString&,
bool aRevoked)>&& aCb);
std::function<bool(BlobImpl*, nsIPrincipal*, const Maybe<nsID>&,
const nsACString&, bool aRevoked)>&& aCb);
// This method returns false if aURI is not a known BlobURL. Otherwise it
// returns true.

View File

@ -2648,8 +2648,9 @@ mozilla::ipc::IPCResult ContentChild::RecvInitBlobURLs(
RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(registration.blob());
MOZ_ASSERT(blobImpl);
BlobURLProtocolHandler::AddDataEntry(registration.url(),
registration.principal(), blobImpl);
BlobURLProtocolHandler::AddDataEntry(
registration.url(), registration.principal(),
registration.agentClusterId(), blobImpl);
// If we have received an already-revoked blobURL, we have to keep it alive
// for a while (see BlobURLProtocolHandler) in order to support pending
// operations such as navigation, download and so on.
@ -3139,11 +3140,12 @@ ContentChild::RecvNotifyPushSubscriptionModifiedObservers(
mozilla::ipc::IPCResult ContentChild::RecvBlobURLRegistration(
const nsCString& aURI, const IPCBlob& aBlob,
const IPC::Principal& aPrincipal) {
const IPC::Principal& aPrincipal, const Maybe<nsID>& aAgentClusterId) {
RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(aBlob);
MOZ_ASSERT(blobImpl);
BlobURLProtocolHandler::AddDataEntry(aURI, aPrincipal, blobImpl);
BlobURLProtocolHandler::AddDataEntry(aURI, aPrincipal, aAgentClusterId,
blobImpl);
return IPC_OK();
}

View File

@ -528,7 +528,7 @@ class ContentChild final : public PContentChild,
mozilla::ipc::IPCResult RecvBlobURLRegistration(
const nsCString& aURI, const IPCBlob& aBlob,
const IPC::Principal& aPrincipal);
const IPC::Principal& aPrincipal, const Maybe<nsID>& aAgentClusterId);
mozilla::ipc::IPCResult RecvBlobURLUnregistration(const nsCString& aURI);

View File

@ -2866,7 +2866,8 @@ bool ContentParent::InitInternal(ProcessPriority aInitialPriority) {
nsTArray<BlobURLRegistrationData> registrations;
BlobURLProtocolHandler::ForEachBlobURL(
[&](BlobImpl* aBlobImpl, nsIPrincipal* aPrincipal,
const nsACString& aURI, bool aRevoked) {
const Maybe<nsID>& aAgentClusterId, const nsACString& aURI,
bool aRevoked) {
nsAutoCString origin;
nsresult rv = aPrincipal->GetOrigin(origin);
if (NS_WARN_IF(NS_FAILED(rv))) {
@ -2890,7 +2891,7 @@ bool ContentParent::InitInternal(ProcessPriority aInitialPriority) {
}
registrations.AppendElement(BlobURLRegistrationData(
nsCString(aURI), ipcBlob, aPrincipal, aRevoked));
nsCString(aURI), ipcBlob, aPrincipal, aAgentClusterId, aRevoked));
rv = TransmitPermissionsForPrincipal(aPrincipal);
Unused << NS_WARN_IF(NS_FAILED(rv));
@ -5491,10 +5492,9 @@ ContentParent::RecvNotifyPushSubscriptionModifiedObservers(
}
/* static */
void ContentParent::BroadcastBlobURLRegistration(const nsACString& aURI,
BlobImpl* aBlobImpl,
nsIPrincipal* aPrincipal,
ContentParent* aIgnoreThisCP) {
void ContentParent::BroadcastBlobURLRegistration(
const nsACString& aURI, BlobImpl* aBlobImpl, nsIPrincipal* aPrincipal,
const Maybe<nsID>& aAgentClusterId, ContentParent* aIgnoreThisCP) {
nsAutoCString origin;
nsresult rv = aPrincipal->GetOrigin(origin);
NS_ENSURE_SUCCESS_VOID(rv);
@ -5524,7 +5524,8 @@ void ContentParent::BroadcastBlobURLRegistration(const nsACString& aURI,
break;
}
Unused << cp->SendBlobURLRegistration(uri, ipcBlob, principal);
Unused << cp->SendBlobURLRegistration(uri, ipcBlob, principal,
aAgentClusterId);
}
}
}
@ -5553,14 +5554,18 @@ void ContentParent::BroadcastBlobURLUnregistration(
}
mozilla::ipc::IPCResult ContentParent::RecvStoreAndBroadcastBlobURLRegistration(
const nsCString& aURI, const IPCBlob& aBlob, const Principal& aPrincipal) {
const nsCString& aURI, const IPCBlob& aBlob, const Principal& aPrincipal,
const Maybe<nsID>& aAgentClusterId) {
RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(aBlob);
if (NS_WARN_IF(!blobImpl)) {
return IPC_FAIL_NO_REASON(this);
}
BlobURLProtocolHandler::AddDataEntry(aURI, aPrincipal, blobImpl);
BroadcastBlobURLRegistration(aURI, blobImpl, aPrincipal, this);
BlobURLProtocolHandler::AddDataEntry(aURI, aPrincipal, aAgentClusterId,
blobImpl);
BroadcastBlobURLRegistration(aURI, blobImpl, aPrincipal, aAgentClusterId,
this);
// We want to store this blobURL, so we can unregister it if the child
// crashes.
mBlobURLs.AppendElement(aURI);
@ -5801,7 +5806,8 @@ void ContentParent::TransmitBlobURLsForPrincipal(nsIPrincipal* aPrincipal) {
nsTArray<BlobURLRegistrationData> registrations;
BlobURLProtocolHandler::ForEachBlobURL(
[&](BlobImpl* aBlobImpl, nsIPrincipal* aBlobPrincipal,
const nsACString& aURI, bool aRevoked) {
const Maybe<nsID>& aAgentClusterId, const nsACString& aURI,
bool aRevoked) {
if (!aPrincipal->Subsumes(aBlobPrincipal)) {
return true;
}
@ -5813,7 +5819,7 @@ void ContentParent::TransmitBlobURLsForPrincipal(nsIPrincipal* aPrincipal) {
}
registrations.AppendElement(BlobURLRegistrationData(
nsCString(aURI), ipcBlob, aPrincipal, aRevoked));
nsCString(aURI), ipcBlob, aPrincipal, aAgentClusterId, aRevoked));
rv = TransmitPermissionsForPrincipal(aPrincipal);
Unused << NS_WARN_IF(NS_FAILED(rv));
@ -6826,60 +6832,24 @@ PFileDescriptorSetParent* ContentParent::SendPFileDescriptorSetConstructor(
}
mozilla::ipc::IPCResult ContentParent::RecvBlobURLDataRequest(
const nsCString& aBlobURL, nsIPrincipal* pTriggeringPrincipal,
nsIPrincipal* pLoadingPrincipal, const OriginAttributes& aOriginAttributes,
const nsCString& aBlobURL, nsIPrincipal* aTriggeringPrincipal,
nsIPrincipal* aLoadingPrincipal, const OriginAttributes& aOriginAttributes,
const Maybe<nsID>& aAgentClusterId,
BlobURLDataRequestResolver&& aResolver) {
RefPtr<BlobImpl> blobImpl;
nsresult rv = NS_GetBlobForBlobURISpec(aBlobURL, getter_AddRefs(blobImpl),
true /* AlsoIfRevoked */);
if (NS_WARN_IF(NS_FAILED(rv))) {
aResolver(rv);
return IPC_OK();
}
if (NS_WARN_IF(!blobImpl)) {
aResolver(NS_ERROR_DOM_BAD_URI);
return IPC_OK();
}
// Since revoked blobs are also retrieved, it is possible that the blob no
// longer exists (due to the 5 second timeout) when execution reaches here
nsIPrincipal* const dataEntryPrincipal =
BlobURLProtocolHandler::GetDataEntryPrincipal(aBlobURL,
true /* AlsoIfRevoked */);
if (!dataEntryPrincipal) {
aResolver(NS_ERROR_DOM_BAD_URI);
return IPC_OK();
}
// We want to be sure that we stop the creation of the channel if the blob
// URL is copy-and-pasted on a different context (ex. private browsing or
// containers).
//
// We also allow the system principal to create the channel regardless of
// the OriginAttributes. This is primarily for the benefit of mechanisms
// like the Download API that explicitly create a channel with the system
// principal and which is never mutated to have a non-zero
// mPrivateBrowsingId or container.
if (NS_WARN_IF(!pLoadingPrincipal ||
!pLoadingPrincipal->IsSystemPrincipal()) &&
NS_WARN_IF(!ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
aOriginAttributes,
BasePrincipal::Cast(dataEntryPrincipal)->OriginAttributesRef()))) {
aResolver(NS_ERROR_DOM_BAD_URI);
return IPC_OK();
}
if (!pTriggeringPrincipal->Subsumes(dataEntryPrincipal)) {
if (!BlobURLProtocolHandler::GetDataEntry(
aBlobURL, getter_AddRefs(blobImpl), aLoadingPrincipal,
aTriggeringPrincipal, aOriginAttributes, aAgentClusterId,
true /* AlsoIfRevoked */)) {
aResolver(NS_ERROR_DOM_BAD_URI);
return IPC_OK();
}
IPCBlob ipcBlob;
rv = IPCBlobUtils::Serialize(blobImpl, this, ipcBlob);
nsresult rv = IPCBlobUtils::Serialize(blobImpl, this, ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
aResolver(rv);

View File

@ -548,6 +548,7 @@ class ContentParent final
static void BroadcastBlobURLRegistration(
const nsACString& aURI, BlobImpl* aBlobImpl, nsIPrincipal* aPrincipal,
const Maybe<nsID>& aAgentClusterId,
ContentParent* aIgnoreThisCP = nullptr);
static void BroadcastBlobURLUnregistration(
@ -555,7 +556,8 @@ class ContentParent final
ContentParent* aIgnoreThisCP = nullptr);
mozilla::ipc::IPCResult RecvStoreAndBroadcastBlobURLRegistration(
const nsCString& aURI, const IPCBlob& aBlob, const Principal& aPrincipal);
const nsCString& aURI, const IPCBlob& aBlob, const Principal& aPrincipal,
const Maybe<nsID>& aAgentCluster);
mozilla::ipc::IPCResult RecvUnstoreAndBroadcastBlobURLUnregistration(
const nsCString& aURI, const Principal& aPrincipal);
@ -701,6 +703,7 @@ class ContentParent final
const nsCString& aBlobURL, nsIPrincipal* pTriggeringPrincipal,
nsIPrincipal* pLoadingPrincipal,
const OriginAttributes& aOriginAttributes,
const Maybe<nsID>& aAgentClusterId,
BlobURLDataRequestResolver&& aResolver);
protected:

View File

@ -235,6 +235,7 @@ struct BlobURLRegistrationData
nsCString url;
IPCBlob blob;
nsIPrincipal principal;
nsID? agentClusterId;
bool revoked;
};
@ -749,7 +750,8 @@ child:
async GetFilesResponse(nsID aID, GetFilesResponseResult aResult);
async BlobURLRegistration(nsCString aURI, IPCBlob aBlob,
Principal aPrincipal);
Principal aPrincipal,
nsID? aAgentClusterId);
async BlobURLUnregistration(nsCString aURI);
@ -1489,7 +1491,8 @@ parent:
async DeleteGetFilesRequest(nsID aID);
async StoreAndBroadcastBlobURLRegistration(nsCString url, IPCBlob blob,
Principal principal);
Principal principal,
nsID? aAgentClusterId);
async UnstoreAndBroadcastBlobURLUnregistration(nsCString url, Principal principal);
@ -1657,7 +1660,12 @@ parent:
async HistoryGo(MaybeDiscardedBrowsingContext aContext,
int32_t aOffset) returns(int32_t requestedIndex);
async BlobURLDataRequest(nsCString aBlobURL, nsIPrincipal aTriggeringPrincipal, nsIPrincipal aLoadingPrincipal, OriginAttributes aOriginAttributes) returns (BlobURLDataRequestResult aResult);
async BlobURLDataRequest(nsCString aBlobURL,
nsIPrincipal aTriggeringPrincipal,
nsIPrincipal aLoadingPrincipal,
OriginAttributes aOriginAttributes,
nsID? aAgentClusterId)
returns (BlobURLDataRequestResult aResult);
both:
async ScriptError(nsString message, nsString sourceName, nsString sourceLine,

View File

@ -31,7 +31,8 @@ void URLMainThread::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
nsContentUtils::ObjectPrincipal(aGlobal.Get());
nsAutoCString url;
aRv = BlobURLProtocolHandler::AddDataEntry(aBlob.Impl(), principal, url);
aRv = BlobURLProtocolHandler::AddDataEntry(aBlob.Impl(), principal,
global->GetAgentClusterId(), url);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
@ -46,11 +47,18 @@ void URLMainThread::CreateObjectURL(const GlobalObject& aGlobal,
ErrorResult& aRv) {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
if (NS_WARN_IF(!global)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsCOMPtr<nsIPrincipal> principal =
nsContentUtils::ObjectPrincipal(aGlobal.Get());
nsAutoCString url;
aRv = BlobURLProtocolHandler::AddDataEntry(&aSource, principal, url);
aRv = BlobURLProtocolHandler::AddDataEntry(&aSource, principal,
global->GetAgentClusterId(), url);
if (NS_WARN_IF(aRv.Failed())) {
return;
}

View File

@ -38,8 +38,8 @@ class CreateURLRunnable : public WorkerMainThreadRunnable {
nsCOMPtr<nsIPrincipal> principal = mWorkerPrivate->GetPrincipal();
nsAutoCString url;
nsresult rv =
BlobURLProtocolHandler::AddDataEntry(mBlobImpl, principal, url);
nsresult rv = BlobURLProtocolHandler::AddDataEntry(
mBlobImpl, principal, Some(mWorkerPrivate->AgentClusterId()), url);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to add data entry for the blob!");