author | Michael Layzell <michael@thelayzells.com> |
Thu, 02 Mar 2017 16:55:09 -0500 | |
changeset 348695 | c2b8ead5376b5f5a3689e4faef9d814c27189ab6 |
parent 348694 | 215ca1b54ff1d363624d81460fe9a7e95d8e4ffd |
child 348696 | dc5c70cb15118d84c0137ea6a0f59b18e69ba73b |
push id | 31533 |
push user | kwierso@gmail.com |
push date | Tue, 21 Mar 2017 23:08:53 +0000 |
treeherder | mozilla-central@8744e9f8eb99 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | baku |
bugs | 1337056 |
milestone | 55.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -1325,16 +1325,20 @@ ContentParent::Init() MOZ_ASSERT(NS_SUCCEEDED(rv)); mIsProfilerActive = true; StartProfiler(currentProfilerParams); } #endif + // Ensure that the default set of permissions are avaliable in the content + // process before we try to load any URIs in it. + EnsurePermissionsByKey(EmptyCString()); + RefPtr<GeckoMediaPluginServiceParent> gmps(GeckoMediaPluginServiceParent::GetSingleton()); gmps->UpdateContentProcessGMPCapabilities(); mScriptableHelper = new ScriptableCPInfo(this); } namespace { @@ -5047,16 +5051,72 @@ void ContentParent::ForceTabPaint(TabParent* aTabParent, uint64_t aLayerObserverEpoch) { if (!mHangMonitorActor) { return; } ProcessHangMonitor::ForcePaint(mHangMonitorActor, aTabParent, aLayerObserverEpoch); } +nsresult +ContentParent::TransmitPermissionsFor(nsIChannel* aChannel) +{ + MOZ_ASSERT(aChannel); +#ifdef MOZ_PERMISSIONS + // If the LOAD_DOCUMENT_URI load flag is not set, we don't need to send down + // permissions, as we won't create a document from this channel. + nsLoadFlags loadFlags; + nsresult rv = aChannel->GetLoadFlags(&loadFlags); + NS_ENSURE_SUCCESS(rv, rv); + if (!(loadFlags & nsIChannel::LOAD_DOCUMENT_URI)) { + return NS_OK; + } + + // Get the principal for the channel result, so that we can get the permission + // key for the document which will be created from this response. + nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); + if (NS_WARN_IF(!ssm)) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr<nsIPrincipal> principal; + rv = ssm->GetChannelResultPrincipal(aChannel, getter_AddRefs(principal)); + NS_ENSURE_SUCCESS(rv, rv); + + // Create the key, and send it down to the content process. + nsAutoCString key; + nsPermissionManager::GetKeyForPrincipal(principal, key); + EnsurePermissionsByKey(key); +#endif + + return NS_OK; +} + +void +ContentParent::EnsurePermissionsByKey(const nsCString& aKey) +{ +#ifdef MOZ_PERMISSIONS + if (mActivePermissionKeys.Contains(aKey)) { + return; + } + mActivePermissionKeys.PutEntry(aKey); + + nsCOMPtr<nsIPermissionManager> permManager = + services::GetPermissionManager(); + + nsTArray<IPC::Permission> perms; + nsresult rv = permManager->GetPermissionsWithKey(aKey, perms); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + Unused << SendSetPermissionsWithKey(aKey, perms); +#endif +} + mozilla::ipc::IPCResult ContentParent::RecvAccumulateChildHistograms( InfallibleTArray<Accumulation>&& aAccumulations) { TelemetryIPC::AccumulateChildHistograms(GeckoProcessType_Content, aAccumulations); return IPC_OK(); }
--- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -635,16 +635,18 @@ public: RecvClassifyLocal(const URIParams& aURI, const nsCString& aTables, nsresult* aRv, nsTArray<nsCString>* aResults) override; // Use the PHangMonitor channel to ask the child to repaint a tab. void ForceTabPaint(TabParent* aTabParent, uint64_t aLayerObserverEpoch); + nsresult TransmitPermissionsFor(nsIChannel* aChannel); + protected: void OnChannelConnected(int32_t pid) override; virtual void ActorDestroy(ActorDestroyReason why) override; bool ShouldContinueFromReplyTimeout() override; void OnVarChanged(const GfxVarUpdate& aVar) override; @@ -775,16 +777,23 @@ private: // Perform any steps necesssary to gracefully shtudown the message // manager and null out mMessageManager. void ShutDownMessageManager(); // Start the force-kill timer on shutdown. void StartForceKillTimer(); + // Ensure that the permissions for the giben Permission key are set in the + // content process. + // + // See nsIPermissionManager::GetPermissionsForKey for more information on + // these keys. + void EnsurePermissionsByKey(const nsCString& aKey); + static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure); static bool AllocateLayerTreeId(ContentParent* aContent, TabParent* aTopLevel, const TabId& aTabId, uint64_t* aId); /** * Get or create the corresponding content parent array to |aContentProcessType|. @@ -1218,16 +1227,18 @@ private: #ifdef NS_PRINTING RefPtr<embedding::PrintingParent> mPrintingParent; #endif // This hashtable is used to run GetFilesHelper objects in the parent process. // GetFilesHelper can be aborted by receiving RecvDeleteGetFilesRequest. nsRefPtrHashtable<nsIDHashKey, GetFilesHelper> mGetFilesPendingRequests; + nsTHashtable<nsCStringHashKey> mActivePermissionKeys; + nsTArray<nsCString> mBlobURLs; #ifdef MOZ_CRASHREPORTER UniquePtr<mozilla::ipc::CrashReporterHost> mCrashReporter; #endif }; } // namespace dom } // namespace mozilla
--- a/netwerk/protocol/ftp/FTPChannelParent.cpp +++ b/netwerk/protocol/ftp/FTPChannelParent.cpp @@ -21,16 +21,17 @@ #include "nsIForcePendingChannel.h" #include "mozilla/ipc/IPCStreamUtils.h" #include "mozilla/ipc/URIUtils.h" #include "mozilla/Unused.h" #include "SerializedLoadContext.h" #include "nsIContentPolicy.h" #include "mozilla/ipc/BackgroundUtils.h" #include "mozilla/LoadInfo.h" +#include "mozilla/dom/ContentParent.h" using namespace mozilla::dom; using namespace mozilla::ipc; #undef LOG #define LOG(args) MOZ_LOG(gFTPLog, mozilla::LogLevel::Debug, args) namespace mozilla { @@ -452,16 +453,23 @@ FTPChannelParent::OnStartRequest(nsIRequ "Cannot divert if listener is unset!"); return mDivertToListener->OnStartRequest(aRequest, aContext); } nsCOMPtr<nsIChannel> chan = do_QueryInterface(aRequest); MOZ_ASSERT(chan); NS_ENSURE_TRUE(chan, NS_ERROR_UNEXPECTED); + // Send down any permissions which are relevant to this URL if we are + // performing a document load. + PContentParent* pcp = Manager()->Manager(); + DebugOnly<nsresult> rv = + static_cast<ContentParent*>(pcp)->TransmitPermissionsFor(chan); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + int64_t contentLength; chan->GetContentLength(&contentLength); nsCString contentType; chan->GetContentType(contentType); nsCString entityID; nsCOMPtr<nsIResumableChannel> resChan = do_QueryInterface(aRequest); MOZ_ASSERT(resChan); // both FTP and HTTP should implement nsIResumableChannel
--- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -37,16 +37,17 @@ #include "nsCORSListenerProxy.h" #include "nsIIPCSerializableInputStream.h" #include "nsIPrompt.h" #include "nsIWindowWatcher.h" #include "nsIDocument.h" #include "nsStringStream.h" #include "nsQueryObject.h" #include "nsIURIClassifier.h" +#include "mozilla/dom/ContentParent.h" using mozilla::BasePrincipal; using namespace mozilla::dom; using namespace mozilla::ipc; namespace mozilla { namespace net { @@ -1121,16 +1122,23 @@ HttpChannelParent::OnStartRequest(nsIReq LOG((" aRequest is not nsHttpChannel")); NS_ERROR("Expecting only nsHttpChannel as aRequest in HttpChannelParent::OnStartRequest"); return NS_ERROR_UNEXPECTED; } MOZ_ASSERT(mChannel == chan, "HttpChannelParent getting OnStartRequest from a different nsHttpChannel instance"); + // Send down any permissions which are relevant to this URL if we are + // performing a document load. + PContentParent* pcp = Manager()->Manager(); + nsresult rv = + static_cast<ContentParent*>(pcp)->TransmitPermissionsFor(chan); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + nsHttpResponseHead *responseHead = chan->GetResponseHead(); nsHttpRequestHead *requestHead = chan->GetRequestHead(); bool isFromCache = false; chan->IsFromCache(&isFromCache); uint32_t expirationTime = nsICacheEntry::NO_EXPIRATION_TIME; chan->GetCacheTokenExpirationTime(&expirationTime); nsCString cachedCharset; chan->GetCacheTokenCachedCharset(cachedCharset); @@ -1187,17 +1195,17 @@ HttpChannelParent::OnStartRequest(nsIReq } nsAutoCString altDataType; chan->GetAlternativeDataType(altDataType); int64_t altDataLen = chan->GetAltDataLength(); // !!! We need to lock headers and please don't forget to unlock them !!! requestHead->Enter(); - nsresult rv = NS_OK; + rv = NS_OK; if (mIPCClosed || !SendOnStartRequest(channelStatus, responseHead ? *responseHead : nsHttpResponseHead(), !!responseHead, requestHead->Headers(), isFromCache, mCacheEntry ? true : false, expirationTime, cachedCharset, secInfoSerialization,
--- a/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp +++ b/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp @@ -10,16 +10,17 @@ #include "nsCharsetSource.h" #include "nsISerializable.h" #include "nsSerializationHelper.h" #include "mozilla/ipc/URIUtils.h" #include "mozilla/net/NeckoParent.h" #include "SerializedLoadContext.h" #include "nsIContentPolicy.h" #include "mozilla/ipc/BackgroundUtils.h" +#include "mozilla/dom/ContentParent.h" using namespace mozilla::ipc; namespace mozilla { namespace net { WyciwygChannelParent::WyciwygChannelParent() : mIPCClosed(false) @@ -315,16 +316,22 @@ WyciwygChannelParent::OnStartRequest(nsI { LOG(("WyciwygChannelParent::OnStartRequest [this=%p]\n", this)); nsresult rv; nsCOMPtr<nsIWyciwygChannel> chan = do_QueryInterface(aRequest, &rv); NS_ENSURE_SUCCESS(rv, rv); + // Send down any permissions which are relevant to this URL if we are + // performing a document load. + PContentParent* pcp = Manager()->Manager(); + rv = static_cast<ContentParent*>(pcp)->TransmitPermissionsFor(chan); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + nsresult status; chan->GetStatus(&status); int64_t contentLength = -1; chan->GetContentLength(&contentLength); int32_t charsetSource = kCharsetUninitialized; nsAutoCString charset;