mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 1658878 - Isolate BlobURLs per agent-cluster, r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D86914
This commit is contained in:
parent
469eb289ea
commit
27d564c279
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
||||
@ -1497,7 +1499,8 @@ parent:
|
||||
async DeleteGetFilesRequest(nsID aID);
|
||||
|
||||
async StoreAndBroadcastBlobURLRegistration(nsCString url, IPCBlob blob,
|
||||
Principal principal);
|
||||
Principal principal,
|
||||
nsID? aAgentClusterId);
|
||||
|
||||
async UnstoreAndBroadcastBlobURLUnregistration(nsCString url, Principal principal);
|
||||
|
||||
@ -1665,7 +1668,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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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!");
|
||||
|
Loading…
Reference in New Issue
Block a user