Bug 1238160 - Set tab context's isolation from frame attr. r=smaug

Renames existing nsFrameLoader::OwnerIsBrowser* methods to add "Moz" prefix for
clarity.

Adds nsFrameLoader::OwnerIsIsolatedMozBrowserFrame which checks the noisolation
attribute of mozbrowser frames, if present.

This is used to set isolation in nsFrameLoader::GetNewTabContext only when true.

MozReview-Commit-ID: Dz02xBoKh1P
This commit is contained in:
J. Ryan Stinnett 2016-02-17 21:31:29 -06:00
parent eb232136f4
commit 23f50b043f
12 changed files with 91 additions and 41 deletions

View File

@ -344,7 +344,7 @@ this.AccessFu = { // jshint ignore:line
{
// Ignore notifications that aren't from a BrowserOrApp
let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
if (!frameLoader.ownerIsBrowserOrAppFrame) {
if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
return;
}
this._handleMessageManager(frameLoader.messageManager);

View File

@ -57,7 +57,7 @@ AppRunner.prototype = {
// get a ref to the app <iframe>
frameLoader.QueryInterface(Ci.nsIFrameLoader);
// Ignore notifications that aren't from a BrowserOrApp
if (!frameLoader.ownerIsBrowserOrAppFrame) {
if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
return;
}

View File

@ -177,7 +177,7 @@ var ErrorPage = {
observe: function errorPageObserve(aSubject, aTopic, aData) {
let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
// Ignore notifications that aren't from a BrowserOrApp
if (!frameLoader.ownerIsBrowserOrAppFrame) {
if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
return;
}
this._listenError(frameLoader);

View File

@ -422,7 +422,7 @@ nsFrameLoader::ReallyStartLoadingInternal()
int32_t flags = nsIWebNavigation::LOAD_FLAGS_NONE;
// Flags for browser frame:
if (OwnerIsBrowserFrame()) {
if (OwnerIsMozBrowserFrame()) {
flags = nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
}
@ -1577,7 +1577,7 @@ nsFrameLoader::SetOwnerContent(Element* aContent)
}
bool
nsFrameLoader::OwnerIsBrowserOrAppFrame()
nsFrameLoader::OwnerIsMozBrowserOrAppFrame()
{
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
return browserFrame ? browserFrame->GetReallyIsBrowserOrApp() : false;
@ -1585,9 +1585,9 @@ nsFrameLoader::OwnerIsBrowserOrAppFrame()
// The xpcom getter version
NS_IMETHODIMP
nsFrameLoader::GetOwnerIsBrowserOrAppFrame(bool* aResult)
nsFrameLoader::GetOwnerIsMozBrowserOrAppFrame(bool* aResult)
{
*aResult = OwnerIsBrowserOrAppFrame();
*aResult = OwnerIsMozBrowserOrAppFrame();
return NS_OK;
}
@ -1615,9 +1615,19 @@ nsFrameLoader::OwnerIsAppFrame()
}
bool
nsFrameLoader::OwnerIsBrowserFrame()
nsFrameLoader::OwnerIsMozBrowserFrame()
{
return OwnerIsBrowserOrAppFrame() && !OwnerIsAppFrame();
return OwnerIsMozBrowserOrAppFrame() && !OwnerIsAppFrame();
}
bool
nsFrameLoader::OwnerIsIsolatedMozBrowserFrame()
{
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
if (!browserFrame) {
return false;
}
return OwnerIsMozBrowserFrame() && browserFrame->GetIsolated();
}
void
@ -1692,7 +1702,7 @@ nsFrameLoader::ShouldUseRemoteProcess()
// If we're an <iframe mozbrowser> and we don't have a "remote" attribute,
// fall back to the default.
if (OwnerIsBrowserOrAppFrame() &&
if (OwnerIsMozBrowserOrAppFrame() &&
!mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::Remote)) {
return Preferences::GetBool("dom.ipc.browser_frames.oop_by_default", false);
@ -1700,7 +1710,7 @@ nsFrameLoader::ShouldUseRemoteProcess()
// Otherwise, we're remote if we have "remote=true" and we're either a
// browser frame or a XUL element.
return (OwnerIsBrowserOrAppFrame() ||
return (OwnerIsMozBrowserOrAppFrame() ||
mOwnerContent->GetNameSpaceID() == kNameSpaceID_XUL) &&
mOwnerContent->AttrValueIs(kNameSpaceID_None,
nsGkAtoms::Remote,
@ -1883,7 +1893,7 @@ nsFrameLoader::MaybeCreateDocShell()
if (OwnerIsAppFrame()) {
// You can't be both an app and a browser frame.
MOZ_ASSERT(!OwnerIsBrowserFrame());
MOZ_ASSERT(!OwnerIsMozBrowserFrame());
nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
MOZ_ASSERT(ownApp);
@ -1895,7 +1905,7 @@ nsFrameLoader::MaybeCreateDocShell()
mDocShell->SetIsApp(ownAppId);
}
if (OwnerIsBrowserFrame()) {
if (OwnerIsMozBrowserFrame()) {
// You can't be both a browser and an app frame.
MOZ_ASSERT(!OwnerIsAppFrame());
@ -1908,7 +1918,7 @@ nsFrameLoader::MaybeCreateDocShell()
mDocShell->SetIsBrowserInsideApp(containingAppId);
}
if (OwnerIsBrowserOrAppFrame()) {
if (OwnerIsMozBrowserOrAppFrame()) {
// For inproc frames, set the docshell properties.
nsCOMPtr<nsIDocShellTreeItem> item = do_GetInterface(docShell);
nsAutoString name;
@ -2249,7 +2259,7 @@ nsFrameLoader::TryRemoteBrowser()
}
// <iframe mozbrowser> gets to skip these checks.
if (!OwnerIsBrowserOrAppFrame()) {
if (!OwnerIsMozBrowserOrAppFrame()) {
if (parentDocShell->ItemType() != nsIDocShellTreeItem::typeChrome) {
return false;
}
@ -2566,7 +2576,7 @@ nsFrameLoader::EnsureMessageManager()
}
if (!mIsTopLevelContent &&
!OwnerIsBrowserOrAppFrame() &&
!OwnerIsMozBrowserOrAppFrame() &&
!IsRemoteFrame() &&
!(mOwnerContent->IsXULElement() &&
mOwnerContent->AttrValueIs(kNameSpaceID_None,
@ -2672,7 +2682,7 @@ nsFrameLoader::SwapRemoteBrowser(nsITabParent* aTabParent)
NS_WARNING("Switching from in-process to out-of-process is not supported.");
return NS_ERROR_NOT_IMPLEMENTED;
}
if (!OwnerIsBrowserOrAppFrame()) {
if (!OwnerIsMozBrowserOrAppFrame()) {
NS_WARNING("Switching process for non-mozbrowser/app frame is not supported.");
return NS_ERROR_NOT_IMPLEMENTED;
}
@ -2823,7 +2833,7 @@ nsFrameLoader::ResetPermissionManagerStatus()
uint32_t appId = nsIScriptSecurityManager::NO_APP_ID;
if (OwnerIsAppFrame()) {
// You can't be both an app and a browser frame.
MOZ_ASSERT(!OwnerIsBrowserFrame());
MOZ_ASSERT(!OwnerIsMozBrowserFrame());
nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
MOZ_ASSERT(ownApp);
@ -2833,7 +2843,7 @@ nsFrameLoader::ResetPermissionManagerStatus()
}
}
if (OwnerIsBrowserFrame()) {
if (OwnerIsMozBrowserFrame()) {
// You can't be both a browser and an app frame.
MOZ_ASSERT(!OwnerIsAppFrame());
@ -2971,7 +2981,7 @@ nsFrameLoader::GetLoadContext(nsILoadContext** aLoadContext)
void
nsFrameLoader::InitializeBrowserAPI()
{
if (OwnerIsBrowserOrAppFrame()) {
if (OwnerIsMozBrowserOrAppFrame()) {
if (!IsRemoteFrame()) {
nsresult rv = EnsureMessageManager();
if (NS_WARN_IF(NS_FAILED(rv))) {
@ -3066,7 +3076,7 @@ nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext,
nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
nsCOMPtr<mozIApplication> containingApp = GetContainingApp();
DocShellOriginAttributes attrs;
attrs.mInIsolatedMozBrowser = OwnerIsBrowserFrame();
attrs.mInIsolatedMozBrowser = OwnerIsIsolatedMozBrowserFrame();
nsCString signedPkgOrigin;
if (!aPackageId.IsEmpty()) {

View File

@ -143,7 +143,7 @@ public:
return mOwnerContent ? mOwnerContent->GetPrimaryFrame() : nullptr;
}
/**
/**
* Return the document that owns this, or null if we don't have
* an owner.
*/
@ -194,7 +194,7 @@ public:
* otherwise we'll discard the old presentation and set the detached
* subdoc view to null. aContainerDoc is the document containing the
* the subdoc frame. This enables us to detect when the containing
* document has changed during reframe, so we can discard the presentation
* document has changed during reframe, so we can discard the presentation
* in that case.
*/
void SetDetachedSubdocView(nsView* aDetachedView,
@ -242,8 +242,9 @@ private:
* Is this a frameloader for a bona fide <iframe mozbrowser> or
* <iframe mozapp>? (I.e., does the frame return true for
* nsIMozBrowserFrame::GetReallyIsBrowserOrApp()?)
* <xul:browser> is not a mozbrowser or app, so this is false for that case.
*/
bool OwnerIsBrowserOrAppFrame();
bool OwnerIsMozBrowserOrAppFrame();
/**
* Is this a frameloader for a bona fide <iframe mozwidget>? (I.e., does the
@ -259,8 +260,18 @@ private:
/**
* Is this a frame loader for a bona fide <iframe mozbrowser>?
* <xul:browser> is not a mozbrowser, so this is false for that case.
*/
bool OwnerIsBrowserFrame();
bool OwnerIsMozBrowserFrame();
/**
* Is this a frame loader for an isolated <iframe mozbrowser>?
*
* By default, mozbrowser frames are isolated. Isolation can be disabled by
* setting the frame's noisolation attribute. Disabling isolation is
* only allowed if the containing document is chrome.
*/
bool OwnerIsIsolatedMozBrowserFrame();
/**
* Get our owning element's app manifest URL, or return the empty string if

View File

@ -657,6 +657,7 @@ GK_ATOM(nodeSet, "node-set")
GK_ATOM(noembed, "noembed")
GK_ATOM(noframes, "noframes")
GK_ATOM(nohref, "nohref")
GK_ATOM(noisolation, "noisolation")
GK_ATOM(nonce, "nonce")
GK_ATOM(none, "none")
GK_ATOM(noresize, "noresize")

View File

@ -150,7 +150,7 @@ interface nsIFrameLoader : nsISupports
const unsigned long EVENT_MODE_NORMAL_DISPATCH = 0x00000000;
/**
* With this event mode, it's the application's responsability to
* With this event mode, it's the application's responsability to
* convert and forward events to the content process
*/
const unsigned long EVENT_MODE_DONT_FORWARD_TO_CHILD = 0x00000001;
@ -196,14 +196,15 @@ interface nsIFrameLoader : nsISupports
[infallible] attribute boolean visible;
/**
* Find out whether the owner content really is a browser or app frame
* Especially, a widget frame is regarded as an app frame.
* Find out whether the owner content really is a mozbrowser or app frame
* Especially, a widget frame is regarded as an app frame. <xul:browser> is
* not considered to be a mozbrowser frame.
*/
readonly attribute boolean ownerIsBrowserOrAppFrame;
readonly attribute boolean ownerIsMozBrowserOrAppFrame;
/**
* Find out whether the owner content really is a widget. If this attribute
* returns true, |ownerIsBrowserOrAppFrame| must return true.
* returns true, |ownerIsMozBrowserOrAppFrame| must return true.
*/
readonly attribute boolean ownerIsWidget;

View File

@ -54,15 +54,15 @@ nsBrowserElement::IsNotWidgetOrThrow(ErrorResult& aRv)
void
nsBrowserElement::InitBrowserElementAPI()
{
bool isBrowserOrApp;
bool isMozBrowserOrApp;
nsCOMPtr<nsIFrameLoader> frameLoader = GetFrameLoader();
NS_ENSURE_TRUE_VOID(frameLoader);
nsresult rv = frameLoader->GetOwnerIsBrowserOrAppFrame(&isBrowserOrApp);
nsresult rv = frameLoader->GetOwnerIsMozBrowserOrAppFrame(&isMozBrowserOrApp);
NS_ENSURE_SUCCESS_VOID(rv);
rv = frameLoader->GetOwnerIsWidget(&mOwnerIsWidget);
NS_ENSURE_SUCCESS_VOID(rv);
if (!isBrowserOrApp) {
if (!isMozBrowserOrApp) {
return;
}
@ -510,13 +510,13 @@ nsBrowserElement::GetAllowedAudioChannels(
return;
}
bool isBrowserOrApp;
aRv = frameLoader->GetOwnerIsBrowserOrAppFrame(&isBrowserOrApp);
bool isMozBrowserOrApp;
aRv = frameLoader->GetOwnerIsMozBrowserOrAppFrame(&isMozBrowserOrApp);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
if (!isBrowserOrApp) {
if (!isMozBrowserOrApp) {
return;
}

View File

@ -550,6 +550,20 @@ nsGenericHTMLFrameElement::GetReallyIsWidget(bool *aOut)
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsGenericHTMLFrameElement::GetIsolated(bool *aOut)
{
*aOut = true;
if (!nsContentUtils::IsSystemPrincipal(NodePrincipal())) {
return NS_OK;
}
// Isolation is only disabled if the attribute is present
*aOut = !HasAttr(kNameSpaceID_None, nsGkAtoms::noisolation);
return NS_OK;
}
/* [infallible] */ NS_IMETHODIMP
nsGenericHTMLFrameElement::GetIsExpectingSystemMessage(bool *aOut)
{
@ -705,4 +719,3 @@ nsGenericHTMLFrameElement::SwapFrameLoaders(nsXULElement& aOtherOwner,
{
aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
}

View File

@ -151,7 +151,7 @@ this.Keyboard = {
}
} else {
// Ignore notifications that aren't from a BrowserOrApp
if (!frameLoader.ownerIsBrowserOrAppFrame) {
if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
return;
}
this.initFormsFrameScript(mm);

View File

@ -43,6 +43,20 @@ interface nsIMozBrowserFrame : nsIDOMMozBrowserFrame
*/
[infallible] readonly attribute boolean reallyIsWidget;
/**
* Gets whether this frame is an isolated frame.
*
* By default, browser frames are isolated, meaning they have a principal
* where OriginAttributes.mIsInIsolatedMozBrowser == true. This isolates
* storage and other origin related items from non-browser apps, xul:browsers,
* etc.
*
* Isolation can be disabled by setting the frame's isolated attribute to
* false. Disabling isolation is only allowed if the containing document has
* browser permission (or equivalent access).
*/
[infallible] readonly attribute boolean isolated;
/**
* This corresponds to the expecting-system-message attribute, which tells us
* whether we should expect that this frame will receive a system message once

View File

@ -869,9 +869,9 @@ ParticularProcessPriorityManager::OnRemoteBrowserFrameShown(nsISupports* aSubjec
}
// Ignore notifications that aren't from a BrowserOrApp
bool isBrowserOrApp;
fl->GetOwnerIsBrowserOrAppFrame(&isBrowserOrApp);
if (isBrowserOrApp) {
bool isMozBrowserOrApp;
fl->GetOwnerIsMozBrowserOrAppFrame(&isMozBrowserOrApp);
if (isMozBrowserOrApp) {
ResetPriority();
}