Bug 1738713 - Fix permission not sent over ipc while non-http/https blob urls exists. r=nika

Differential Revision: https://phabricator.services.mozilla.com/D130857
This commit is contained in:
Luca Greco 2021-11-15 17:30:19 +00:00
parent 0bf9787775
commit d9085976ad
4 changed files with 110 additions and 4 deletions

View File

@ -1698,10 +1698,6 @@ void ContentParent::Init() {
Unused << SendInitProfiler(ProfilerParent::CreateForProcess(OtherPid()));
// Ensure that the default set of permissions are avaliable in the content
// process before we try to load any URIs in it.
EnsurePermissionsByKey(""_ns, ""_ns);
RefPtr<GeckoMediaPluginServiceParent> gmps(
GeckoMediaPluginServiceParent::GetSingleton());
gmps->UpdateContentProcessGMPCapabilities();
@ -3123,6 +3119,13 @@ bool ContentParent::InitInternal(ProcessPriority aInitialPriority) {
}
#endif
// Ensure that the default set of permissions are avaliable in the content
// process before we try to load any URIs in it.
//
// NOTE: All default permissions has to be transmitted to the child process
// before the blob urls in the for loop below (See Bug 1738713 comment 12).
EnsurePermissionsByKey(""_ns, ""_ns);
{
nsTArray<BlobURLRegistrationData> registrations;
BlobURLProtocolHandler::ForEachBlobURL(

View File

@ -3166,6 +3166,15 @@ PermissionManager::GetAllKeysForPrincipal(nsIPrincipal* aPrincipal) {
// Don't force strip origin attributes.
GetKeyForPrincipal(prin, false, pair->first);
// On origins with a derived key set to an empty string
// (basically any non-web URI scheme), we want to make sure
// to return earlier, and leave [("", "")] as the resulting
// pairs (but still run the same debug assertions near the
// end of this method).
if (pair->first.IsEmpty()) {
break;
}
Unused << GetOriginFromPrincipal(prin, false, pair->second);
prin = prin->GetNextSubDomainPrincipal();
// Get the next subdomain principal and loop back around.

View File

@ -0,0 +1,89 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const { ExtensionTestUtils } = ChromeUtils.import(
"resource://testing-common/ExtensionXPCShellUtils.jsm"
);
add_task(async function test_permissions_sent_over_ipc_on_bloburl() {
const ssm = Services.scriptSecurityManager;
const pm = Services.perms;
// setup a profile.
do_get_profile();
async function assertExpectedContentPage(contentPage) {
const [processType, remoteType, principalSpec] = await page.spawn(
[],
async () => {
return [
Services.appinfo.processType,
Services.appinfo.remoteType,
this.content.document.nodePrincipal.spec,
];
}
);
equal(
processType,
Services.appinfo.PROCESS_TYPE_CONTENT,
"Got a content process"
);
equal(remoteType, "file", "Got a file child process");
equal(principalSpec, principal.spec, "Got the expected document principal");
}
function getChildProcessID(contentPage) {
return contentPage.spawn([], () => Services.appinfo.processID);
}
async function assertHasAllowedPermission(contentPage, perm) {
const isPermissionAllowed = await contentPage.spawn(
[perm],
permName =>
Services.perms.getPermissionObject(
this.content.document.nodePrincipal,
permName,
true
)?.capability === Services.perms.ALLOW_ACTION
);
ok(isPermissionAllowed, `Permission "${perm}" allowed as expected`);
}
let file = do_get_file(".", true);
let fileURI = Services.io.newFileURI(file);
const principal = ssm.createContentPrincipal(fileURI, {});
info(`Add a test permission to the document principal: ${principal.spec}`);
pm.addFromPrincipal(principal, "test/perm", pm.ALLOW_ACTION);
info("Test expected permission is propagated into the child process");
let page = await ExtensionTestUtils.loadContentPage(fileURI.spec);
const childID1 = await getChildProcessID(page);
await assertExpectedContentPage(page);
await assertHasAllowedPermission(page, "test/perm");
await page.close();
// Ensure this blob url does not prevent permissions to be propagated
// to a new child process.
info("Create a blob url for a non http/https principal");
const blob = new Blob();
const blobURL = URL.createObjectURL(blob);
ok(blobURL, "Got a blob URL");
info("Test expected permission is still propagated");
page = await ExtensionTestUtils.loadContentPage(fileURI.spec);
const childID2 = await getChildProcessID(page);
await assertExpectedContentPage(page);
Assert.notEqual(childID1, childID2, "Got a new child process as expected");
await assertHasAllowedPermission(page, "test/perm");
await page.close();
URL.revokeObjectURL(blobURL);
page = await ExtensionTestUtils.loadContentPage(fileURI.spec);
const childID3 = await getChildProcessID(page);
await assertExpectedContentPage(page);
Assert.notEqual(childID2, childID3, "Got a new child process as expected");
await assertHasAllowedPermission(page, "test/perm");
await page.close();
});

View File

@ -46,3 +46,8 @@ skip-if = toolkit == 'android' # Android doesn't use places
[test_permmanager_oa_strip.js]
[test_permmanager_remove_add_update.js]
skip-if = win10_2004 && bits == 64 # Bug 1718292
[test_permmanager_ipc.js]
# This test is meant to run on a multi process mode
# and with file urls loaded in their own child process.
skip-if = !e10s
firefox-appdir = browser