Bug 1774306 - Ensure VideoFrame is transferred within same origin r=smaug

Add a same-origin check to ensure transferring VideoFrame from one
origin to another doesn't work. Without the check, VideoFrames can be
transferred across the origins when e10s is disabled.

Depends on D163194

Differential Revision: https://phabricator.services.mozilla.com/D163195
This commit is contained in:
Chun-Min Chang 2023-01-17 18:03:00 +00:00
Родитель 6315ebfc23
Коммит 617c183b5c
3 изменённых файлов: 39 добавлений и 10 удалений

Просмотреть файл

@ -1283,7 +1283,12 @@ StructuredCloneHolder::CustomReadTransferHandler(
static_cast<VideoFrame::TransferredData*>(aContent);
nsCOMPtr<nsIGlobalObject> global = mGlobal;
RefPtr<VideoFrame> frame = VideoFrame::FromTransferred(global.get(), data);
// aContent will be released in CustomFreeTransferHandler if frame is null.
if (!frame) {
return false;
}
delete data;
aContent = nullptr;
JS::Rooted<JS::Value> value(aCx);
if (!GetOrCreateDOMReflector(aCx, frame, &value)) {
@ -1523,10 +1528,11 @@ void StructuredCloneHolder::CustomFreeTransferHandler(
if (StaticPrefs::dom_media_webcodecs_enabled() &&
aTag == SCTAG_DOM_VIDEOFRAME &&
CloneScope() == StructuredCloneScope::SameProcess) {
MOZ_ASSERT(aContent);
VideoFrame::TransferredData* data =
static_cast<VideoFrame::TransferredData*>(aContent);
delete data;
if (aContent) {
VideoFrame::TransferredData* data =
static_cast<VideoFrame::TransferredData*>(aContent);
delete data;
}
return;
}
}

Просмотреть файл

@ -1977,10 +1977,8 @@ bool VideoFrame::WriteStructuredClone(JSStructuredCloneWriter* aWriter,
RefPtr<layers::Image> image(mResource->mImage.get());
// The serialization is limited to the same process scope so it's ok to
// serialize a reference instead of a copy.
nsIPrincipal* principal = mParent->PrincipalOrNull();
nsCOMPtr<nsIURI> uri = principal ? principal->GetURI() : nullptr;
aHolder->VideoFrameImages().AppendElement(
VideoFrameImageData{image.forget(), uri});
VideoFrameImageData{image.forget(), GetPrincipalURI()});
return !(
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, SCTAG_DOM_VIDEOFRAME, index)) ||
@ -2011,7 +2009,7 @@ UniquePtr<VideoFrame::TransferredData> VideoFrame::Transfer() {
Resource r = mResource.extract();
auto frame = MakeUnique<TransferredData>(
r.mImage.get(), r.mFormat.PixelFormat(), mVisibleRect, mDisplaySize,
mDuration, mTimestamp, mColorSpace);
mDuration, mTimestamp, mColorSpace, GetPrincipalURI());
Close();
return frame;
}
@ -2022,12 +2020,23 @@ already_AddRefed<VideoFrame> VideoFrame::FromTransferred(
nsIGlobalObject* aGlobal, TransferredData* aData) {
MOZ_ASSERT(aData);
if (!IsSameOrigin(aGlobal, aData->mPrincipalURI.get())) {
return nullptr;
}
return MakeAndAddRef<VideoFrame>(
aGlobal, aData->mImage, aData->mFormat.PixelFormat(),
aData->mImage->GetSize(), aData->mVisibleRect, aData->mDisplaySize,
aData->mDuration.take(), aData->mTimestamp, aData->mColorSpace);
}
already_AddRefed<nsIURI> VideoFrame::GetPrincipalURI() const {
AssertIsOnOwningThread();
nsIPrincipal* principal = mParent->PrincipalOrNull();
return principal ? principal->GetURI() : nullptr;
}
/*
* VideoFrame::Format
*

Просмотреть файл

@ -152,8 +152,7 @@ class VideoFrame final : public nsISupports, public nsWrapperCache {
StructuredCloneHolder* aHolder) const;
// [Transferable] implementations: Transfer, FromTransferred
struct FrameData;
using TransferredData = FrameData;
struct TransferredData;
UniquePtr<TransferredData> Transfer();
@ -207,10 +206,25 @@ class VideoFrame final : public nsISupports, public nsWrapperCache {
const VideoColorSpaceInit mColorSpace;
};
struct TransferredData : FrameData {
TransferredData(layers::Image* aImage, const VideoPixelFormat& aFormat,
gfx::IntRect aVisibleRect, gfx::IntSize aDisplaySize,
Maybe<uint64_t> aDuration, int64_t aTimestamp,
const VideoColorSpaceInit& aColorSpace,
already_AddRefed<nsIURI> aPrincipalURI)
: FrameData(aImage, aFormat, aVisibleRect, aDisplaySize, aDuration,
aTimestamp, aColorSpace),
mPrincipalURI(aPrincipalURI) {}
const nsCOMPtr<nsIURI> mPrincipalURI;
};
private:
// VideoFrame can run on either main thread or worker thread.
void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(VideoFrame); }
already_AddRefed<nsIURI> GetPrincipalURI() const;
// A class representing the VideoFrame's data.
class Resource final {
public: