Bug 1781277: Implement DiskStorageLimit RFP target. r=tjr a=pascalc
Differential Revision: https://phabricator.services.mozilla.com/D256111
This commit is contained in:
committed by
pchevrel@mozilla.com
parent
3392ea7ae8
commit
714d506ada
@@ -1298,6 +1298,12 @@ void GetJarPrefix(bool aInIsolatedMozBrowser, nsACString& aJarPrefix) {
|
||||
// This method computes and returns our best guess for the temporary storage
|
||||
// limit (in bytes), based on disk capacity.
|
||||
Result<uint64_t, nsresult> GetTemporaryStorageLimit(nsIFile& aStorageDir) {
|
||||
if (nsContentUtils::ShouldResistFingerprinting(
|
||||
"The storage limit is set only once and not webpage specific.",
|
||||
RFPTarget::DiskStorageLimit)) {
|
||||
return nsRFPService::GetSpoofedStorageLimit();
|
||||
}
|
||||
|
||||
// The fixed limit pref can be used to override temporary storage limit
|
||||
// calculation.
|
||||
if (StaticPrefs::dom_quotaManager_temporaryStorage_fixedLimit() >= 0) {
|
||||
@@ -7171,17 +7177,21 @@ void QuotaManager::SetThumbnailPrivateIdentityId(
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t QuotaManager::GetGroupLimit() const {
|
||||
/* static */
|
||||
uint64_t QuotaManager::GetGroupLimitForLimit(uint64_t aLimit) {
|
||||
// To avoid one group evicting all the rest, limit the amount any one group
|
||||
// can use to 20% resp. a fifth. To prevent individual sites from using
|
||||
// exorbitant amounts of storage where there is a lot of free space, cap the
|
||||
// group limit to 10GB.
|
||||
const auto x = std::min<uint64_t>(mTemporaryStorageLimit / 5, 10 GB);
|
||||
const auto x = std::min<uint64_t>(aLimit / 5, 10 GB);
|
||||
|
||||
// In low-storage situations, make an exception (while not exceeding the total
|
||||
// storage limit).
|
||||
return std::min<uint64_t>(mTemporaryStorageLimit,
|
||||
std::max<uint64_t>(x, 10 MB));
|
||||
return std::min<uint64_t>(aLimit, std::max<uint64_t>(x, 10 MB));
|
||||
}
|
||||
|
||||
uint64_t QuotaManager::GetGroupLimit() const {
|
||||
return GetGroupLimitForLimit(mTemporaryStorageLimit);
|
||||
}
|
||||
|
||||
std::pair<uint64_t, uint64_t> QuotaManager::GetUsageAndLimitForEstimate(
|
||||
|
||||
@@ -665,6 +665,7 @@ class QuotaManager final : public BackgroundThreadObject {
|
||||
void SetThumbnailPrivateIdentityId(uint32_t aThumbnailPrivateIdentityId);
|
||||
|
||||
uint64_t GetGroupLimit() const;
|
||||
static uint64_t GetGroupLimitForLimit(uint64_t aLimit);
|
||||
|
||||
std::pair<uint64_t, uint64_t> GetUsageAndLimitForEstimate(
|
||||
const OriginMetadata& aOriginMetadata);
|
||||
|
||||
70
dom/quota/test/xpcshell/test_temporaryStorageRFP.js
Normal file
70
dom/quota/test/xpcshell/test_temporaryStorageRFP.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
const { AppConstants } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/AppConstants.sys.mjs"
|
||||
);
|
||||
|
||||
async function testSteps() {
|
||||
const principal = getPrincipal("http://example.com");
|
||||
const GiB = 1024 * 1024 * 1024;
|
||||
|
||||
// Set the limit to some random value that is less than 50 GiB.
|
||||
const globalLimitBytes = 1 * GiB;
|
||||
const globalLimitKib = globalLimitBytes / 1024;
|
||||
|
||||
setGlobalLimit(globalLimitKib);
|
||||
|
||||
let request = init();
|
||||
await requestFinished(request);
|
||||
|
||||
request = initTemporaryStorage();
|
||||
await requestFinished(request);
|
||||
|
||||
request = estimateOrigin(principal);
|
||||
await requestFinished(request);
|
||||
|
||||
const perGroupPercentage = 0.2;
|
||||
const expectedGroupLimitBytes = Math.floor(
|
||||
globalLimitBytes * perGroupPercentage
|
||||
);
|
||||
is(expectedGroupLimitBytes, request.result.limit);
|
||||
|
||||
// Verify the RFP override is applied.
|
||||
request = reset();
|
||||
await requestFinished(request);
|
||||
|
||||
let spoofedLimitBytes = 50 * GiB;
|
||||
if (AppConstants.platform == "android") {
|
||||
spoofedLimitBytes = 32 * GiB;
|
||||
}
|
||||
|
||||
Services.prefs.setBoolPref("privacy.resistFingerprinting", true);
|
||||
|
||||
request = init();
|
||||
await requestFinished(request);
|
||||
|
||||
request = initTemporaryStorage();
|
||||
await requestFinished(request);
|
||||
|
||||
request = estimateOrigin(principal);
|
||||
await requestFinished(request);
|
||||
|
||||
const expectedSpoofedGroupLimitBytes = Math.floor(
|
||||
spoofedLimitBytes * perGroupPercentage
|
||||
);
|
||||
is(
|
||||
expectedSpoofedGroupLimitBytes,
|
||||
request.result.limit,
|
||||
"RFP limit should be applied"
|
||||
);
|
||||
|
||||
Services.prefs.clearUserPref("privacy.resistFingerprinting");
|
||||
|
||||
resetGlobalLimit();
|
||||
|
||||
request = reset();
|
||||
await requestFinished(request);
|
||||
}
|
||||
@@ -162,6 +162,8 @@ skip-if = ["inc_origin_init"]
|
||||
# a conditioned profile in the first place.
|
||||
run-if = ["!condprof"]
|
||||
|
||||
["test_temporaryStorageRFP.js"]
|
||||
|
||||
["test_unaccessedOrigins.js"]
|
||||
|
||||
["test_unknownFiles.js"]
|
||||
|
||||
@@ -99,6 +99,8 @@ ITEM_VALUE(WebGPUIsFallbackAdapter, 65)
|
||||
ITEM_VALUE(WebGPUSubgroupSizes, 66)
|
||||
ITEM_VALUE(JSLocalePrompt, 67)
|
||||
ITEM_VALUE(ScreenAvailToResolution, 68)
|
||||
// ITEM_VALUE(UseHardcodedFontSubstitutes, 69) // Bug 1845105 isn't uplifted to ESR yet.
|
||||
ITEM_VALUE(DiskStorageLimit, 70)
|
||||
|
||||
|
||||
// !!! Don't forget to update kDefaultFingerprintingProtections in nsRFPService.cpp
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "mozilla/dom/KeyboardEventBinding.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "mozilla/dom/MediaDeviceInfoBinding.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
#include "mozilla/fallible.h"
|
||||
#include "mozilla/XorShift128PlusRNG.h"
|
||||
#include "mozilla/dom/CanvasUtils.h"
|
||||
@@ -2677,3 +2678,17 @@ CSSIntRect nsRFPService::GetSpoofedScreenAvailSize(const nsRect& aRect,
|
||||
return CSSIntRect::FromAppUnitsRounded(
|
||||
nsRect{0, 0, aRect.width, aRect.height - spoofedHeightOffset});
|
||||
}
|
||||
|
||||
/* static */
|
||||
uint64_t nsRFPService::GetSpoofedStorageLimit() {
|
||||
uint64_t gib = 1024ULL * 1024ULL * 1024ULL; // 1 GiB
|
||||
#ifdef ANDROID
|
||||
uint64_t limit = 32ULL * gib; // 32 GiB
|
||||
#else
|
||||
uint64_t limit = 50ULL * gib; // 50 GiB
|
||||
#endif
|
||||
MOZ_ASSERT(limit / 5 ==
|
||||
dom::quota::QuotaManager::GetGroupLimitForLimit(limit));
|
||||
|
||||
return limit;
|
||||
}
|
||||
|
||||
@@ -414,6 +414,8 @@ class nsRFPService final : public nsIObserver, public nsIRFPService {
|
||||
static CSSIntRect GetSpoofedScreenAvailSize(const nsRect& aRect, float aScale,
|
||||
bool aIsFullscreen);
|
||||
|
||||
static uint64_t GetSpoofedStorageLimit();
|
||||
|
||||
private:
|
||||
nsresult Init();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user