Backed out 4 changesets (bug 1195173) for webtest failures. r=oranges on a CLOSED TREE

Backed out changeset 92b7c3c6e875 (bug 1195173)
Backed out changeset d026d6f185ab (bug 1195173)
Backed out changeset 3b51d7bae8e4 (bug 1195173)
Backed out changeset a75bb8d083e8 (bug 1195173)
This commit is contained in:
Sebastian Hengst 2016-01-27 20:24:52 +01:00
parent 1c7e71986f
commit d7b50c7dc0
6 changed files with 139 additions and 152 deletions

View File

@ -143,17 +143,8 @@ DoContentSecurityChecks(nsIURI* aURI, nsILoadInfo* aLoadInfo)
break;
}
case nsIContentPolicy::TYPE_IMAGE: {
MOZ_ASSERT(false, "contentPolicyType not supported yet");
break;
}
case nsIContentPolicy::TYPE_STYLESHEET: {
mimeTypeGuess = NS_LITERAL_CSTRING("text/css");
requestingContext = aLoadInfo->LoadingNode();
break;
}
case nsIContentPolicy::TYPE_IMAGE:
case nsIContentPolicy::TYPE_STYLESHEET:
case nsIContentPolicy::TYPE_OBJECT:
case nsIContentPolicy::TYPE_DOCUMENT: {
MOZ_ASSERT(false, "contentPolicyType not supported yet");

View File

@ -48,6 +48,7 @@
#include "nsThreadUtils.h"
#include "nsGkAtoms.h"
#include "nsIThreadInternal.h"
#include "nsCORSListenerProxy.h"
#include "nsINetworkPredictor.h"
#include "mozilla/dom/ShadowRoot.h"
#include "mozilla/dom/URL.h"
@ -74,14 +75,16 @@ using namespace mozilla::dom;
* The CSS Loader gets requests to load various sorts of style sheets:
* inline style from <style> elements, linked style, @import-ed child
* sheets, non-document sheets. The loader handles the following tasks:
* 1) Creation of the actual style sheet objects: CreateSheet()
* 2) setting of the right media, title, enabled state, etc on the
*
* 1) Checking whether the load is allowed: CheckLoadAllowed()
* 2) Creation of the actual style sheet objects: CreateSheet()
* 3) setting of the right media, title, enabled state, etc on the
* sheet: PrepareSheet()
* 3) Insertion of the sheet in the proper cascade order:
* 4) Insertion of the sheet in the proper cascade order:
* InsertSheetInDoc() and InsertChildSheet()
* 4) Load of the sheet: LoadSheet() including security checks
* 5) Parsing of the sheet: ParseSheet()
* 6) Cleanup: SheetComplete()
* 5) Load of the sheet: LoadSheet()
* 6) Parsing of the sheet: ParseSheet()
* 7) Cleanup: SheetComplete()
*
* The detailed documentation for these functions is found with the
* function implementations.
@ -1015,30 +1018,61 @@ Loader::ObsoleteSheet(nsIURI* aURI)
return NS_OK;
}
/**
* CheckLoadAllowed will return success if the load is allowed,
* failure otherwise.
*
* @param aSourcePrincipal the principal of the node or document or parent
* sheet loading the sheet
* @param aTargetURI the uri of the sheet to be loaded
* @param aContext the node owning the sheet. This is the element or document
* owning the stylesheet (possibly indirectly, for child sheets)
*/
nsresult
Loader::CheckContentPolicy(nsIPrincipal* aSourcePrincipal,
nsIURI* aTargetURI,
nsISupports* aContext,
bool aIsPreload)
Loader::CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
nsIURI* aTargetURI,
nsISupports* aContext,
bool aIsPreload)
{
nsContentPolicyType contentPolicyType =
aIsPreload ? nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD
: nsIContentPolicy::TYPE_INTERNAL_STYLESHEET;
LOG(("css::Loader::CheckLoadAllowed"));
int16_t shouldLoad = nsIContentPolicy::ACCEPT;
nsresult rv = NS_CheckContentLoadPolicy(contentPolicyType,
aTargetURI,
aSourcePrincipal,
aContext,
NS_LITERAL_CSTRING("text/css"),
nullptr, //extra param
&shouldLoad,
nsContentUtils::GetContentPolicy(),
nsContentUtils::GetSecurityManager());
if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
return NS_ERROR_CONTENT_BLOCKED;
}
return NS_OK;
nsresult rv;
if (aSourcePrincipal) {
// Check with the security manager
nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
rv =
secMan->CheckLoadURIWithPrincipal(aSourcePrincipal, aTargetURI,
nsIScriptSecurityManager::ALLOW_CHROME);
if (NS_FAILED(rv)) { // failure is normal here; don't warn
return rv;
}
LOG((" Passed security check"));
// Check with content policy
nsContentPolicyType contentPolicyType =
aIsPreload ? nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD
: nsIContentPolicy::TYPE_INTERNAL_STYLESHEET;
int16_t shouldLoad = nsIContentPolicy::ACCEPT;
rv = NS_CheckContentLoadPolicy(contentPolicyType,
aTargetURI,
aSourcePrincipal,
aContext,
NS_LITERAL_CSTRING("text/css"),
nullptr, //extra param
&shouldLoad,
nsContentUtils::GetContentPolicy(),
nsContentUtils::GetSecurityManager());
if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
LOG((" Load blocked by content policy"));
return NS_ERROR_CONTENT_BLOCKED;
}
}
return NS_OK;
}
/**
@ -1412,8 +1446,19 @@ Loader::LoadSheet(SheetLoadData* aLoadData,
return NS_BINDING_ABORTED;
}
bool inherit = false;
nsIPrincipal* triggeringPrincipal = aLoadData->mLoaderPrincipal;
if (!triggeringPrincipal) {
if (triggeringPrincipal) {
rv = NS_URIChainHasFlags(aLoadData->mURI,
nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
&inherit);
inherit =
((NS_SUCCEEDED(rv) && inherit) ||
(nsContentUtils::URIIsLocalFile(aLoadData->mURI) &&
NS_SUCCEEDED(aLoadData->mLoaderPrincipal->
CheckMayLoad(aLoadData->mURI, false, false))));
}
else {
triggeringPrincipal = nsContentUtils::GetSystemPrincipal();
}
@ -1442,14 +1487,6 @@ Loader::LoadSheet(SheetLoadData* aLoadData,
mDocument);
}
nsSecurityFlags securityFlags =
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS |
nsILoadInfo::SEC_ALLOW_CHROME;
nsContentPolicyType contentPolicyType =
aIsPreload ? nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD
: nsIContentPolicy::TYPE_INTERNAL_STYLESHEET;
// Just load it
nsCOMPtr<nsIChannel> channel;
// Note that we are calling NS_NewChannelWithTriggeringPrincipal() with both
@ -1462,8 +1499,8 @@ Loader::LoadSheet(SheetLoadData* aLoadData,
aLoadData->mURI,
aLoadData->mRequestingNode,
triggeringPrincipal,
securityFlags,
contentPolicyType);
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER);
}
else {
// either we are loading something inside a document, in which case
@ -1474,17 +1511,13 @@ Loader::LoadSheet(SheetLoadData* aLoadData,
rv = NS_NewChannel(getter_AddRefs(channel),
aLoadData->mURI,
triggeringPrincipal,
securityFlags,
contentPolicyType);
}
if (NS_FAILED(rv)) {
LOG_ERROR((" Failed to create channel"));
SheetComplete(aLoadData, rv);
return rv;
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER);
}
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIInputStream> stream;
rv = channel->Open2(getter_AddRefs(stream));
rv = channel->Open(getter_AddRefs(stream));
if (NS_FAILED(rv)) {
LOG_ERROR((" Failed to open URI synchronously"));
@ -1548,30 +1581,20 @@ Loader::LoadSheet(SheetLoadData* aLoadData,
return NS_OK;
}
nsCOMPtr<nsILoadGroup> loadGroup;
if (mDocument) {
loadGroup = mDocument->GetDocumentLoadGroup();
// load for a document with no loadgrup indicates that something is
// completely bogus, let's bail out early.
if (!loadGroup) {
LOG_ERROR((" Failed to query loadGroup from document"));
SheetComplete(aLoadData, NS_ERROR_UNEXPECTED);
return NS_ERROR_UNEXPECTED;
}
}
#ifdef DEBUG
mSyncCallback = true;
#endif
CORSMode ourCORSMode = aLoadData->mSheet->GetCORSMode();
nsSecurityFlags securityFlags =
ourCORSMode == CORS_NONE
? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS
: nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
if (ourCORSMode == CORS_USE_CREDENTIALS) {
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
nsCOMPtr<nsILoadGroup> loadGroup;
if (mDocument) {
loadGroup = mDocument->GetDocumentLoadGroup();
NS_ASSERTION(loadGroup,
"No loadgroup for stylesheet; onload will fire early");
}
nsLoadFlags securityFlags = nsILoadInfo::SEC_NORMAL;
if (inherit) {
securityFlags |= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
}
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
nsContentPolicyType contentPolicyType =
aIsPreload ? nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD
@ -1667,13 +1690,35 @@ Loader::LoadSheet(SheetLoadData* aLoadData,
return rv;
}
nsCOMPtr<nsIStreamListener> channelListener;
CORSMode ourCORSMode = aLoadData->mSheet->GetCORSMode();
if (ourCORSMode != CORS_NONE) {
bool withCredentials = (ourCORSMode == CORS_USE_CREDENTIALS);
LOG((" Doing CORS-enabled load; credentials %d", withCredentials));
RefPtr<nsCORSListenerProxy> corsListener =
new nsCORSListenerProxy(streamLoader, aLoadData->mLoaderPrincipal,
withCredentials);
rv = corsListener->Init(channel, DataURIHandling::Allow);
if (NS_FAILED(rv)) {
#ifdef DEBUG
mSyncCallback = false;
#endif
LOG_ERROR((" Initial CORS check failed"));
SheetComplete(aLoadData, rv);
return rv;
}
channelListener = corsListener;
} else {
channelListener = streamLoader;
}
if (mDocument) {
mozilla::net::PredictorLearn(aLoadData->mURI, mDocument->GetDocumentURI(),
nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE,
mDocument);
}
rv = channel->AsyncOpen2(streamLoader);
rv = channel->AsyncOpen(channelListener, nullptr);
#ifdef DEBUG
mSyncCallback = false;
@ -2016,9 +2061,10 @@ Loader::LoadStyleLink(nsIContent* aElement,
if (!context) {
context = mDocument;
}
nsresult rv = CheckLoadAllowed(principal, aURL, context, false);
if (NS_FAILED(rv)) return rv;
nsresult rv = CheckContentPolicy(principal, aURL, context, false);
NS_ENSURE_SUCCESS(rv, rv);
LOG((" Passed load check"));
StyleSheetState state;
RefPtr<CSSStyleSheet> sheet;
@ -2150,8 +2196,10 @@ Loader::LoadChildSheet(CSSStyleSheet* aParentSheet,
}
nsIPrincipal* principal = aParentSheet->Principal();
nsresult rv = CheckContentPolicy(principal, aURL, context, false);
NS_ENSURE_SUCCESS(rv, rv);
nsresult rv = CheckLoadAllowed(principal, aURL, context, false);
if (NS_FAILED(rv)) return rv;
LOG((" Passed load check"));
SheetLoadData* parentData = nullptr;
nsCOMPtr<nsICSSLoaderObserver> observer;
@ -2303,8 +2351,10 @@ Loader::InternalLoadNonDocumentSheet(nsIURI* aURL,
return NS_ERROR_NOT_AVAILABLE;
}
nsresult rv = CheckContentPolicy(aOriginPrincipal, aURL, mDocument, aIsPreload);
NS_ENSURE_SUCCESS(rv, rv);
nsresult rv = CheckLoadAllowed(aOriginPrincipal, aURL, mDocument, aIsPreload);
if (NS_FAILED(rv)) {
return rv;
}
StyleSheetState state;
bool isAlternate;

View File

@ -446,10 +446,15 @@ private:
RefPtr<CSSStyleSheet>& aSheet,
void* aUserData);
nsresult CheckContentPolicy(nsIPrincipal* aSourcePrincipal,
nsIURI* aTargetURI,
nsISupports* aContext,
bool aIsPreload);
// Note: null aSourcePrincipal indicates that the content policy and
// CheckLoadURI checks should be skipped.
// aIsPreload indicates whether the html parser preloads that
// stylesheet or if it is a regular load.
nsresult CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
nsIURI* aTargetURI,
nsISupports* aContext,
bool aIsPreload);
// For inline style, the aURI param is null, but the aLinkingContent
// must be non-null then. The loader principal must never be null

View File

@ -293,4 +293,3 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262,
skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262, :visited support) b2g-debug(bug 870262, :visited support) b2g-desktop(bug 870262, :visited support)
[test_webkit_box_orient.html]
[test_webkit_device_pixel_ratio.html]
[test_asyncopen2.html]

View File

@ -1,54 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1195173
-->
<head>
<title>Bug 1195173 - Test asyncOpen2 security exception</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<!-- Note: the following stylesheet does not exist -->
<link rel="stylesheet" id="myCSS" type="text/css" href="file:///home/foo/bar.css">
</head>
<body onload="checkCSS()">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1195173">Mozilla Bug 1195173</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<script type="application/javascript">
/*
* Description of the test:
* Accessing a stylesheet that got blocked by asyncOpen2 should
* throw an exception.
*/
SimpleTest.waitForExplicitFinish();
function checkCSS()
{
try {
// accessing tests/SimpleTest/test.css should not throw
var goodCSS = document.styleSheets[0].cssRules
ok(true, "accessing test.css should be allowed");
}
catch(e) {
ok(false, "accessing test.css should be allowed");
}
try {
// accessing file:///home/foo/bar.css should throw
var badCSS = document.styleSheets[1].cssRules
ok(false, "accessing bar.css should throw");
}
catch(e) {
ok(true, "accessing bar.css should throw");
}
SimpleTest.finish();
}
</script>
</body>
</html>

View File

@ -104,9 +104,8 @@ ExtensionProtocolHandler::SubstituteChannel(nsIURI* aURI,
const char* kToType = "text/css";
nsCOMPtr<nsIInputStream> inputStream;
if (aLoadInfo &&
aLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS) {
// If the channel needs to enforce CORS, we need to open the channel async.
if (aLoadInfo && aLoadInfo->GetSecurityMode()) {
// Certain security checks require an async channel.
nsCOMPtr<nsIOutputStream> outputStream;
rv = NS_NewPipe(getter_AddRefs(inputStream), getter_AddRefs(outputStream),
@ -129,14 +128,11 @@ ExtensionProtocolHandler::SubstituteChannel(nsIURI* aURI,
rv = (*result)->AsyncOpen2(converter);
} else {
// Stylesheet loads for extension content scripts require a sync channel.
// Stylesheet loads for extension content scripts require a sync channel,
// but fortunately do not invoke security checks.
nsCOMPtr<nsIInputStream> sourceStream;
if (aLoadInfo && aLoadInfo->GetEnforceSecurity()) {
rv = (*result)->Open2(getter_AddRefs(sourceStream));
} else {
rv = (*result)->Open(getter_AddRefs(sourceStream));
}
rv = (*result)->Open(getter_AddRefs(sourceStream));
NS_ENSURE_SUCCESS(rv, rv);
rv = convService->Convert(sourceStream, kFromType, kToType,