Skip to content

Commit 0b66c5a

Browse files
FKLCfkilic@mozilla.com
authored andcommitted
Bug 1918690: Check canvas permission in RandomizePixels function. r=tjr,gfx-reviewers,nical
Differential Revision: https://phabricator.services.mozilla.com/D222869
1 parent f37c650 commit 0b66c5a

File tree

12 files changed

+72
-36
lines changed

12 files changed

+72
-36
lines changed

dom/canvas/CanvasRenderingContext2D.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2144,8 +2144,9 @@ UniquePtr<uint8_t[]> CanvasRenderingContext2D::GetImageBuffer(
21442144

21452145
if (ret && ShouldResistFingerprinting(RFPTarget::CanvasRandomization)) {
21462146
nsRFPService::RandomizePixels(
2147-
GetCookieJarSettings(), ret.get(), out_imageSize->width,
2148-
out_imageSize->height, out_imageSize->width * out_imageSize->height * 4,
2147+
GetCookieJarSettings(), PrincipalOrNull(), ret.get(),
2148+
out_imageSize->width, out_imageSize->height,
2149+
out_imageSize->width * out_imageSize->height * 4,
21492150
SurfaceFormat::A8R8G8B8_UINT32);
21502151
}
21512152

@@ -6395,9 +6396,10 @@ nsresult CanvasRenderingContext2D::GetImageDataArray(
63956396
// holder.
63966397

63976398
const IntSize size = readback->GetSize();
6398-
nsRFPService::RandomizePixels(
6399-
GetCookieJarSettings(), rawData.mData, size.width, size.height,
6400-
size.height * size.width * 4, SurfaceFormat::A8R8G8B8_UINT32);
6399+
nsRFPService::RandomizePixels(GetCookieJarSettings(), PrincipalOrNull(),
6400+
rawData.mData, size.width, size.height,
6401+
size.height * size.width * 4,
6402+
SurfaceFormat::A8R8G8B8_UINT32);
64016403
}
64026404

64036405
JS::AutoCheckCannotGC nogc;

dom/canvas/CanvasUtils.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,10 +322,6 @@ ImageExtraction ImageExtractionResult(dom::HTMLCanvasElement* aCanvasElement,
322322
}
323323

324324
if (ownerDoc->ShouldResistFingerprinting(RFPTarget::CanvasRandomization)) {
325-
if (GetCanvasExtractDataPermission(aPrincipal) ==
326-
nsIPermissionManager::ALLOW_ACTION) {
327-
return ImageExtraction::Unrestricted;
328-
}
329325
return ImageExtraction::Randomize;
330326
}
331327

dom/canvas/CanvasUtils.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,16 @@ bool HasDrawWindowPrivilege(JSContext* aCx, JSObject* aObj);
5959
// Check if the context has permission to use OffscreenCanvas.
6060
bool IsOffscreenCanvasEnabled(JSContext* aCx, JSObject* aObj);
6161

62+
// Check if the principal has "canvas" permission.
63+
uint32_t GetCanvasExtractDataPermission(nsIPrincipal& aPrincipal);
64+
6265
// Check site-specific permission and display prompt if appropriate.
6366
bool IsImageExtractionAllowed(dom::Document* aDocument, JSContext* aCx,
6467
nsIPrincipal& aPrincipal);
6568

69+
bool IsImageExtractionAllowed(dom::OffscreenCanvas* aOffscreenCanvas,
70+
JSContext* aCx, nsIPrincipal& aPrincipal);
71+
6672
uint32_t GetCanvasExtractDataPermission(nsIPrincipal& aPrincipal);
6773

6874
enum class ImageExtraction {

dom/canvas/ClientWebGLContext.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,7 +1345,8 @@ UniquePtr<uint8_t[]> ClientWebGLContext::GetImageBuffer(
13451345

13461346
if (ShouldResistFingerprinting(RFPTarget::CanvasRandomization)) {
13471347
return gfxUtils::GetImageBufferWithRandomNoise(
1348-
dataSurface, premultAlpha, GetCookieJarSettings(), out_format);
1348+
dataSurface, premultAlpha, GetCookieJarSettings(), PrincipalOrNull(),
1349+
out_format);
13491350
}
13501351

13511352
return gfxUtils::GetImageBuffer(dataSurface, premultAlpha, out_format);
@@ -1366,7 +1367,7 @@ ClientWebGLContext::GetInputStream(const char* mimeType,
13661367
if (ShouldResistFingerprinting(RFPTarget::CanvasRandomization)) {
13671368
return gfxUtils::GetInputStreamWithRandomNoise(
13681369
dataSurface, premultAlpha, mimeType, encoderOptions,
1369-
GetCookieJarSettings(), out_stream);
1370+
GetCookieJarSettings(), PrincipalOrNull(), out_stream);
13701371
}
13711372

13721373
return gfxUtils::GetInputStream(dataSurface, premultAlpha, mimeType,

dom/canvas/ImageBitmapRenderingContext.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ mozilla::UniquePtr<uint8_t[]> ImageBitmapRenderingContext::GetImageBuffer(
195195

196196
if (ret && ShouldResistFingerprinting(RFPTarget::CanvasRandomization)) {
197197
nsRFPService::RandomizePixels(
198-
GetCookieJarSettings(), ret.get(), data->GetSize().width,
199-
data->GetSize().height,
198+
GetCookieJarSettings(), PrincipalOrNull(), ret.get(),
199+
data->GetSize().width, data->GetSize().height,
200200
data->GetSize().width * data->GetSize().height * 4,
201201
gfx::SurfaceFormat::A8R8G8B8_UINT32);
202202
}

dom/canvas/OffscreenCanvas.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "ImageBitmap.h"
2727
#include "ImageBitmapRenderingContext.h"
2828
#include "nsContentUtils.h"
29+
#include "nsIPermissionManager.h"
2930
#include "nsProxyRelease.h"
3031
#include "WebGLChild.h"
3132

@@ -503,8 +504,11 @@ already_AddRefed<Promise> OffscreenCanvas::ConvertToBlob(
503504

504505
RefPtr<EncodeCompleteCallback> callback =
505506
CreateEncodeCompleteCallback(promise);
506-
bool usePlaceholder =
507-
ShouldResistFingerprinting(RFPTarget::CanvasImageExtractionPrompt);
507+
508+
bool usePlaceholder = mCurrentContext && mCurrentContext->PrincipalOrNull() &&
509+
!CanvasUtils::IsImageExtractionAllowed(
510+
this, nsContentUtils::GetCurrentJSContext(),
511+
*mCurrentContext->PrincipalOrNull());
508512
CanvasRenderingContextHelper::ToBlob(callback, type, encodeOptions,
509513
/* aUsingCustomOptions */ false,
510514
usePlaceholder, aRv);
@@ -545,8 +549,10 @@ already_AddRefed<Promise> OffscreenCanvas::ToBlob(JSContext* aCx,
545549

546550
RefPtr<EncodeCompleteCallback> callback =
547551
CreateEncodeCompleteCallback(promise);
548-
bool usePlaceholder =
549-
ShouldResistFingerprinting(RFPTarget::CanvasImageExtractionPrompt);
552+
bool usePlaceholder = mCurrentContext && mCurrentContext->PrincipalOrNull() &&
553+
!CanvasUtils::IsImageExtractionAllowed(
554+
this, nsContentUtils::GetCurrentJSContext(),
555+
*mCurrentContext->PrincipalOrNull());
550556
CanvasRenderingContextHelper::ToBlob(aCx, callback, aType, aParams,
551557
usePlaceholder, aRv);
552558

dom/canvas/OffscreenCanvasDisplayHelper.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -577,9 +577,21 @@ UniquePtr<uint8_t[]> OffscreenCanvasDisplayHelper::GetImageBuffer(
577577
}
578578

579579
if (resistFingerprinting) {
580+
nsIPrincipal* principal;
581+
{
582+
MutexAutoLock lock(mMutex);
583+
if (mCanvasElement) {
584+
principal = mCanvasElement->NodePrincipal();
585+
}
586+
if (mOffscreenCanvas) {
587+
principal = mOffscreenCanvas->GetParentObject()
588+
? mOffscreenCanvas->GetParentObject()->PrincipalOrNull()
589+
: nullptr;
590+
}
591+
}
580592
nsRFPService::RandomizePixels(
581-
cookieJarSettings, imageBuffer.get(), dataSurface->GetSize().width,
582-
dataSurface->GetSize().height,
593+
cookieJarSettings, principal, imageBuffer.get(),
594+
dataSurface->GetSize().width, dataSurface->GetSize().height,
583595
dataSurface->GetSize().width * dataSurface->GetSize().height * 4,
584596
gfx::SurfaceFormat::A8R8G8B8_UINT32);
585597
}

dom/webgpu/CanvasContext.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -353,9 +353,10 @@ mozilla::UniquePtr<uint8_t[]> CanvasContext::GetImageBuffer(
353353
*out_imageSize = dataSurface->GetSize();
354354

355355
if (ShouldResistFingerprinting(RFPTarget::CanvasRandomization)) {
356-
gfxUtils::GetImageBufferWithRandomNoise(
357-
dataSurface,
358-
/* aIsAlphaPremultiplied */ true, GetCookieJarSettings(), &*out_format);
356+
gfxUtils::GetImageBufferWithRandomNoise(dataSurface,
357+
/* aIsAlphaPremultiplied */ true,
358+
GetCookieJarSettings(),
359+
PrincipalOrNull(), &*out_format);
359360
}
360361

361362
return gfxUtils::GetImageBuffer(dataSurface, /* aIsAlphaPremultiplied */ true,
@@ -374,9 +375,9 @@ NS_IMETHODIMP CanvasContext::GetInputStream(const char* aMimeType,
374375
RefPtr<gfx::DataSourceSurface> dataSurface = snapshot->GetDataSurface();
375376

376377
if (ShouldResistFingerprinting(RFPTarget::CanvasRandomization)) {
377-
gfxUtils::GetInputStreamWithRandomNoise(
378+
return gfxUtils::GetInputStreamWithRandomNoise(
378379
dataSurface, /* aIsAlphaPremultiplied */ true, aMimeType,
379-
aEncoderOptions, GetCookieJarSettings(), aStream);
380+
aEncoderOptions, GetCookieJarSettings(), PrincipalOrNull(), aStream);
380381
}
381382

382383
return gfxUtils::GetInputStream(dataSurface, /* aIsAlphaPremultiplied */ true,

gfx/thebes/gfxUtils.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,13 +1613,14 @@ UniquePtr<uint8_t[]> gfxUtils::GetImageBuffer(gfx::DataSourceSurface* aSurface,
16131613
/* static */
16141614
UniquePtr<uint8_t[]> gfxUtils::GetImageBufferWithRandomNoise(
16151615
gfx::DataSourceSurface* aSurface, bool aIsAlphaPremultiplied,
1616-
nsICookieJarSettings* aCookieJarSettings, int32_t* outFormat) {
1616+
nsICookieJarSettings* aCookieJarSettings, nsIPrincipal* aPrincipal,
1617+
int32_t* outFormat) {
16171618
UniquePtr<uint8_t[]> imageBuffer =
16181619
GetImageBuffer(aSurface, aIsAlphaPremultiplied, outFormat);
16191620

16201621
nsRFPService::RandomizePixels(
1621-
aCookieJarSettings, imageBuffer.get(), aSurface->GetSize().width,
1622-
aSurface->GetSize().height,
1622+
aCookieJarSettings, aPrincipal, imageBuffer.get(),
1623+
aSurface->GetSize().width, aSurface->GetSize().height,
16231624
aSurface->GetSize().width * aSurface->GetSize().height * 4,
16241625
SurfaceFormat::A8R8G8B8_UINT32);
16251626

@@ -1651,7 +1652,8 @@ nsresult gfxUtils::GetInputStream(gfx::DataSourceSurface* aSurface,
16511652
nsresult gfxUtils::GetInputStreamWithRandomNoise(
16521653
gfx::DataSourceSurface* aSurface, bool aIsAlphaPremultiplied,
16531654
const char* aMimeType, const nsAString& aEncoderOptions,
1654-
nsICookieJarSettings* aCookieJarSettings, nsIInputStream** outStream) {
1655+
nsICookieJarSettings* aCookieJarSettings, nsIPrincipal* aPrincipal,
1656+
nsIInputStream** outStream) {
16551657
nsCString enccid("@mozilla.org/image/encoder;2?type=");
16561658
enccid += aMimeType;
16571659
nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(enccid.get());
@@ -1667,8 +1669,8 @@ nsresult gfxUtils::GetInputStreamWithRandomNoise(
16671669
}
16681670

16691671
nsRFPService::RandomizePixels(
1670-
aCookieJarSettings, imageBuffer.get(), aSurface->GetSize().width,
1671-
aSurface->GetSize().height,
1672+
aCookieJarSettings, aPrincipal, imageBuffer.get(),
1673+
aSurface->GetSize().width, aSurface->GetSize().height,
16721674
aSurface->GetSize().width * aSurface->GetSize().height * 4,
16731675
SurfaceFormat::A8R8G8B8_UINT32);
16741676

gfx/thebes/gfxUtils.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,8 @@ class gfxUtils {
400400

401401
static mozilla::UniquePtr<uint8_t[]> GetImageBufferWithRandomNoise(
402402
DataSourceSurface* aSurface, bool aIsAlphaPremultiplied,
403-
nsICookieJarSettings* aCookieJarSettings, int32_t* outFormat);
403+
nsICookieJarSettings* aCookieJarSettings, nsIPrincipal* aPrincipal,
404+
int32_t* outFormat);
404405

405406
static nsresult GetInputStream(DataSourceSurface* aSurface,
406407
bool aIsAlphaPremultiplied,
@@ -411,7 +412,8 @@ class gfxUtils {
411412
static nsresult GetInputStreamWithRandomNoise(
412413
DataSourceSurface* aSurface, bool aIsAlphaPremultiplied,
413414
const char* aMimeType, const nsAString& aEncoderOptions,
414-
nsICookieJarSettings* aCookieJarSettings, nsIInputStream** outStream);
415+
nsICookieJarSettings* aCookieJarSettings, nsIPrincipal* aPrincipal,
416+
nsIInputStream** outStream);
415417

416418
static void RemoveShaderCacheFromDiskIfNecessary();
417419

0 commit comments

Comments
 (0)