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 // Ignore notifications that aren't from a BrowserOrApp
let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader); let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
if (!frameLoader.ownerIsBrowserOrAppFrame) { if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
return; return;
} }
this._handleMessageManager(frameLoader.messageManager); this._handleMessageManager(frameLoader.messageManager);

View File

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

View File

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

View File

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

View File

@ -143,7 +143,7 @@ public:
return mOwnerContent ? mOwnerContent->GetPrimaryFrame() : nullptr; return mOwnerContent ? mOwnerContent->GetPrimaryFrame() : nullptr;
} }
/** /**
* Return the document that owns this, or null if we don't have * Return the document that owns this, or null if we don't have
* an owner. * an owner.
*/ */
@ -194,7 +194,7 @@ public:
* otherwise we'll discard the old presentation and set the detached * otherwise we'll discard the old presentation and set the detached
* subdoc view to null. aContainerDoc is the document containing the * subdoc view to null. aContainerDoc is the document containing the
* the subdoc frame. This enables us to detect when the containing * 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. * in that case.
*/ */
void SetDetachedSubdocView(nsView* aDetachedView, void SetDetachedSubdocView(nsView* aDetachedView,
@ -242,8 +242,9 @@ private:
* Is this a frameloader for a bona fide <iframe mozbrowser> or * Is this a frameloader for a bona fide <iframe mozbrowser> or
* <iframe mozapp>? (I.e., does the frame return true for * <iframe mozapp>? (I.e., does the frame return true for
* nsIMozBrowserFrame::GetReallyIsBrowserOrApp()?) * 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 * 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>? * 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 * 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(noembed, "noembed")
GK_ATOM(noframes, "noframes") GK_ATOM(noframes, "noframes")
GK_ATOM(nohref, "nohref") GK_ATOM(nohref, "nohref")
GK_ATOM(noisolation, "noisolation")
GK_ATOM(nonce, "nonce") GK_ATOM(nonce, "nonce")
GK_ATOM(none, "none") GK_ATOM(none, "none")
GK_ATOM(noresize, "noresize") GK_ATOM(noresize, "noresize")

View File

@ -150,7 +150,7 @@ interface nsIFrameLoader : nsISupports
const unsigned long EVENT_MODE_NORMAL_DISPATCH = 0x00000000; 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 * convert and forward events to the content process
*/ */
const unsigned long EVENT_MODE_DONT_FORWARD_TO_CHILD = 0x00000001; const unsigned long EVENT_MODE_DONT_FORWARD_TO_CHILD = 0x00000001;
@ -196,14 +196,15 @@ interface nsIFrameLoader : nsISupports
[infallible] attribute boolean visible; [infallible] attribute boolean visible;
/** /**
* Find out whether the owner content really is a browser or 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. * 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 * 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; readonly attribute boolean ownerIsWidget;

View File

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

View File

@ -550,6 +550,20 @@ nsGenericHTMLFrameElement::GetReallyIsWidget(bool *aOut)
return NS_OK; 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 /* [infallible] */ NS_IMETHODIMP
nsGenericHTMLFrameElement::GetIsExpectingSystemMessage(bool *aOut) nsGenericHTMLFrameElement::GetIsExpectingSystemMessage(bool *aOut)
{ {
@ -705,4 +719,3 @@ nsGenericHTMLFrameElement::SwapFrameLoaders(nsXULElement& aOtherOwner,
{ {
aError.Throw(NS_ERROR_NOT_IMPLEMENTED); aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
} }

View File

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

View File

@ -43,6 +43,20 @@ interface nsIMozBrowserFrame : nsIDOMMozBrowserFrame
*/ */
[infallible] readonly attribute boolean reallyIsWidget; [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 * This corresponds to the expecting-system-message attribute, which tells us
* whether we should expect that this frame will receive a system message once * 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 // Ignore notifications that aren't from a BrowserOrApp
bool isBrowserOrApp; bool isMozBrowserOrApp;
fl->GetOwnerIsBrowserOrAppFrame(&isBrowserOrApp); fl->GetOwnerIsMozBrowserOrAppFrame(&isMozBrowserOrApp);
if (isBrowserOrApp) { if (isMozBrowserOrApp) {
ResetPriority(); ResetPriority();
} }