Bug 1038756: Refactor SetUpChannelOwner to ChannelShouldInheritPrincipal (r=bz)

This commit is contained in:
Christoph Kerschbaumer
2014-07-17 16:07:58 -07:00
parent 9e6399cd21
commit 967667dee4
6 changed files with 84 additions and 86 deletions

View File

@@ -1965,26 +1965,21 @@ public:
static nsresult URIInheritsSecurityContext(nsIURI *aURI, bool *aResult);
/**
* Set the given principal as the principal on the nsILoadInfo of the given
* channel, and tell the channel to inherit it if needed. aPrincipal may be
* null, in which case this method is a no-op.
* Called before a channel is created to query whether the new
* channel should inherit the principal.
*
* If aLoadingPrincipal is not null, aURI must be the URI of aChannel. If
* aInheritForAboutBlank is true, then about:blank will be told to inherit the
* principal. If aForceInherit is true, the channel will be told to inherit
* the principal no matter what, as long as the principal is not null.
* The argument aLoadingPrincipal must not be null. The argument
* aURI must be the URI of the new channel. If aInheritForAboutBlank
* is true, then about:blank will be told to inherit the principal.
* If aForceInherit is true, the new channel will be told to inherit
* the principal no matter what.
*
* If aIsSandboxed is true, then aLoadingPrincipal must not be null. In this
* case, the owner on the channel, if any, will be reset to null and the
* nsILoadInfo will say the channel should be sandboxed.
*
* The return value is whether the channel was told to inherit the principal.
* The return value is whether the new channel should inherit
* the principal.
*/
static bool SetUpChannelOwner(nsIPrincipal* aLoadingPrincipal,
nsIChannel* aChannel,
static bool ChannelShouldInheritPrincipal(nsIPrincipal* aLoadingPrincipal,
nsIURI* aURI,
bool aInheritForAboutBlank,
bool aIsSandboxed,
bool aForceInherit);
static nsresult Btoa(const nsAString& aBinaryData,

View File

@@ -6440,37 +6440,14 @@ nsContentUtils::URIInheritsSecurityContext(nsIURI *aURI, bool *aResult)
// static
bool
nsContentUtils::SetUpChannelOwner(nsIPrincipal* aLoadingPrincipal,
nsIChannel* aChannel,
nsContentUtils::ChannelShouldInheritPrincipal(nsIPrincipal* aLoadingPrincipal,
nsIURI* aURI,
bool aInheritForAboutBlank,
bool aIsSandboxed,
bool aForceInherit)
{
nsCOMPtr<nsIPrincipal> loadingPrincipal = aLoadingPrincipal;
if (!loadingPrincipal) {
if (!aIsSandboxed) {
// Nothing to do here
return false;
}
MOZ_ASSERT(aLoadingPrincipal, "Can not check inheritance without a principal");
// Go ahead and create a nullprincipal to use as our loading principal,
// since we need to make sure to sandbox the load but we have no clue who's
// loading us.
loadingPrincipal = do_CreateInstance(NS_NULLPRINCIPAL_CONTRACTID);
if (!loadingPrincipal) {
NS_RUNTIMEABORT("Failed to create a principal?");
}
}
// If we're sandboxed, make sure to clear any owner the channel
// might already have.
if (aIsSandboxed) {
aChannel->SetOwner(nullptr);
}
// Set the loadInfo of the channel, but only tell the channel to
// inherit if it can't provide its own security context.
// Only tell the channel to inherit if it can't provide its own security context.
//
// XXX: If this is ever changed, check all callers for what owners
// they're passing in. In particular, see the code and
@@ -6500,19 +6477,12 @@ nsContentUtils::SetUpChannelOwner(nsIPrincipal* aLoadingPrincipal,
// based on its own codebase later.
//
(URIIsLocalFile(aURI) &&
NS_SUCCEEDED(loadingPrincipal->CheckMayLoad(aURI, false, false)) &&
NS_SUCCEEDED(aLoadingPrincipal->CheckMayLoad(aURI, false, false)) &&
// One more check here. CheckMayLoad will always return true for the
// system principal, but we do NOT want to inherit in that case.
!IsSystemPrincipal(loadingPrincipal));
!IsSystemPrincipal(aLoadingPrincipal));
}
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(loadingPrincipal,
inherit ?
nsILoadInfo::eInheritPrincipal : nsILoadInfo::eDontInheritPrincipal,
aIsSandboxed ? nsILoadInfo::eSandboxed : nsILoadInfo::eNotSandboxed);
aChannel->SetLoadInfo(loadInfo);
return inherit && !aIsSandboxed;
return inherit;
}
/* static */

View File

@@ -2504,10 +2504,23 @@ nsObjectLoadingContent::OpenChannel()
nsRefPtr<ObjectInterfaceRequestorShim> shim =
new ObjectInterfaceRequestorShim(this);
bool isSandBoxed = doc->GetSandboxFlags() & SANDBOXED_ORIGIN;
bool inherit = nsContentUtils::ChannelShouldInheritPrincipal(thisContent->NodePrincipal(),
mURI,
true, // aInheritForAboutBlank
false); // aForceInherit
nsSecurityFlags securityFlags = nsILoadInfo::SEC_NORMAL;
if (inherit) {
securityFlags |= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
}
if (isSandBoxed) {
securityFlags |= nsILoadInfo::SEC_SANDBOXED;
}
rv = NS_NewChannel(getter_AddRefs(chan),
mURI,
thisContent,
nsILoadInfo::SEC_NORMAL,
securityFlags,
nsIContentPolicy::TYPE_OBJECT,
channelPolicy,
group, // aLoadGroup
@@ -2529,14 +2542,6 @@ nsObjectLoadingContent::OpenChannel()
}
}
// Set up the channel's principal and such, like nsDocShell::DoURILoad does.
// If the content being loaded should be sandboxed with respect to origin we
// tell SetUpChannelOwner that.
nsContentUtils::SetUpChannelOwner(thisContent->NodePrincipal(), chan, mURI,
true,
doc->GetSandboxFlags() & SANDBOXED_ORIGIN,
false);
nsCOMPtr<nsIScriptChannel> scriptChannel = do_QueryInterface(chan);
if (scriptChannel) {
// Allow execution against our context if the principals match

View File

@@ -9369,7 +9369,7 @@ nsDocShell::InternalLoad(nsIURI * aURI,
{
bool willInherit;
// This condition needs to match the one in
// nsContentUtils::SetUpChannelOwner.
// nsContentUtils::ChannelShouldInheritPrincipal.
// Except we reverse the rv check to be safe in case
// nsContentUtils::URIInheritsSecurityContext fails here and
// succeeds there.
@@ -10147,8 +10147,19 @@ nsDocShell::DoURILoad(nsIURI * aURI,
requestingNode = mScriptGlobal->GetExtantDoc();
}
}
bool isSandBoxed = mSandboxFlags & SANDBOXED_ORIGIN;
// only inherit if we have a requestingPrincipal
bool inherit = false;
nsCOMPtr<nsIPrincipal> requestingPrincipal = do_QueryInterface(aOwner);
if (!requestingPrincipal && aReferrerURI) {
if (requestingPrincipal) {
inherit = nsContentUtils::ChannelShouldInheritPrincipal(requestingPrincipal,
aURI,
true, // aInheritForAboutBlank
isSrcdoc);
}
else if (!requestingPrincipal && aReferrerURI) {
rv = CreatePrincipalFromReferrer(aReferrerURI,
getter_AddRefs(requestingPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
@@ -10157,12 +10168,20 @@ nsDocShell::DoURILoad(nsIURI * aURI,
requestingPrincipal = nsContentUtils::GetSystemPrincipal();
}
nsSecurityFlags securityFlags = nsILoadInfo::SEC_NORMAL;
if (inherit) {
securityFlags |= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
}
if (isSandBoxed) {
securityFlags |= nsILoadInfo::SEC_SANDBOXED;
}
if (!isSrcdoc) {
rv = NS_NewChannelInternal(getter_AddRefs(channel),
aURI,
requestingNode,
requestingPrincipal,
nsILoadInfo::SEC_NORMAL,
securityFlags,
aContentPolicyType,
channelPolicy,
nullptr, // loadGroup
@@ -10221,7 +10240,7 @@ nsDocShell::DoURILoad(nsIURI * aURI,
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(requestingPrincipal,
requestingNode,
nsILoadInfo::SEC_NORMAL,
securityFlags,
aContentPolicyType);
channel->SetLoadInfo(loadInfo);
}
@@ -10386,11 +10405,6 @@ nsDocShell::DoURILoad(nsIURI * aURI,
}
}
nsCOMPtr<nsIPrincipal> ownerPrincipal = do_QueryInterface(aOwner);
nsContentUtils::SetUpChannelOwner(ownerPrincipal, channel, aURI, true,
mSandboxFlags & SANDBOXED_ORIGIN,
isSrcdoc);
nsCOMPtr<nsIScriptChannel> scriptChannel = do_QueryInterface(channel);
if (scriptChannel) {
// Allow execution against our context if the principals match

View File

@@ -663,10 +663,23 @@ static nsresult NewImageChannel(nsIChannel **aResult,
aLoadFlags |= nsIChannel::LOAD_CLASSIFY_URI;
nsCOMPtr<nsIPrincipal> requestingPrincipal = aLoadingPrincipal;
if (!requestingPrincipal) {
bool isSandBoxed = false;
// only inherit if we have a principal
bool inherit = false;
if (requestingPrincipal) {
inherit = nsContentUtils::ChannelShouldInheritPrincipal(requestingPrincipal,
aURI,
false, // aInheritForAboutBlank
false); // aForceInherit
}
else {
requestingPrincipal = nsContentUtils::GetSystemPrincipal();
}
nsCOMPtr<nsINode> requestingNode = do_QueryInterface(aRequestingContext);
nsSecurityFlags securityFlags = nsILoadInfo::SEC_NORMAL;
if (inherit) {
securityFlags |= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
}
// Note we are calling NS_NewChannelInternal() here with a node and a principal.
// This is for things like background images that are specified by user
// stylesheets, where the document is being styled, but the principal is that
@@ -675,7 +688,7 @@ static nsresult NewImageChannel(nsIChannel **aResult,
aURI,
requestingNode,
requestingPrincipal,
nsILoadInfo::SEC_NORMAL,
securityFlags,
nsIContentPolicy::TYPE_IMAGE,
aPolicy,
nullptr, // loadGroup
@@ -685,7 +698,7 @@ static nsresult NewImageChannel(nsIChannel **aResult,
if (NS_FAILED(rv))
return rv;
*aForcePrincipalCheckForCacheEntry = false;
*aForcePrincipalCheckForCacheEntry = inherit && !isSandBoxed;
// Initialize HTTP-specific attributes
newHttpChannel = do_QueryInterface(*aResult);
@@ -711,11 +724,6 @@ static nsresult NewImageChannel(nsIChannel **aResult,
p->AdjustPriority(priority);
}
bool setOwner = nsContentUtils::SetUpChannelOwner(aLoadingPrincipal,
*aResult, aURI, false,
false, false);
*aForcePrincipalCheckForCacheEntry = setOwner;
// Create a new loadgroup for this new channel, using the old group as
// the parent. The indirection keeps the channel insulated from cancels,
// but does allow a way for this revalidation to be associated with at

View File

@@ -246,6 +246,12 @@ NS_NewChannelInternal(nsIChannel** outChannel,
channel->SetLoadInfo(aLoadInfo);
// If we're sandboxed, make sure to clear any owner the channel
// might already have.
if (aLoadInfo->GetLoadingSandboxed()) {
channel->SetOwner(nullptr);
}
channel.forget(outChannel);
return NS_OK;
}