From 767d4dafd25b65fb4c591a182926c6308c89505f Mon Sep 17 00:00:00 2001 From: Honza Bambas Date: Fri, 23 Feb 2018 08:00:00 +0200 Subject: [PATCH] Bug 1440663 - Add a preference to limit document opening data conversion recursion depth to nsDocumentOpenInfo, r=smaug --HG-- extra : histedit_source : 939bf4439875a7d88617d36cbf060e9d728c65fb --- modules/libpref/init/all.js | 5 +++++ uriloader/base/nsURILoader.cpp | 32 +++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 21edf6e72e78..5f3b06b8dbe4 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -6005,3 +6005,8 @@ pref("layers.omtp.paint-workers", 1); #endif pref("layers.omtp.release-capture-on-main-thread", false); pref("layers.omtp.dump-capture", false); + +// Limits the depth of recursive conversion of data when opening +// a content to view. This is mostly intended to prevent infinite +// loops with faulty converters involved. +pref("general.document_open_conversion_depth_limit", 20); diff --git a/uriloader/base/nsURILoader.cpp b/uriloader/base/nsURILoader.cpp index 90d56dee15c0..ff0d8079c099 100644 --- a/uriloader/base/nsURILoader.cpp +++ b/uriloader/base/nsURILoader.cpp @@ -49,6 +49,7 @@ #include "mozilla/Attributes.h" #include "mozilla/IntegerPrintfMacros.h" #include "mozilla/Preferences.h" +#include "mozilla/Unused.h" #include "nsContentUtils.h" mozilla::LazyLogModule nsURILoader::mLog("URILoader"); @@ -60,6 +61,17 @@ mozilla::LazyLogModule nsURILoader::mLog("URILoader"); #define NS_PREF_DISABLE_BACKGROUND_HANDLING \ "security.exthelperapp.disable_background_handling" +static uint32_t sConvertDataLimit = 20; + +static bool InitPreferences() +{ + nsresult rv = mozilla::Preferences::AddUintVarCache( + &sConvertDataLimit, + "general.document_open_conversion_depth_limit", + 20); + return NS_SUCCEEDED(rv); +} + /** * The nsDocumentOpenInfo contains the state required when a single * document is being opened in order to discover the content type... @@ -157,6 +169,11 @@ protected: * nsIURIContentListeners. */ RefPtr mURILoader; + + /** + * Limit of data conversion depth to prevent infinite conversion loops + */ + uint32_t mDataConversionDepthLimit; }; NS_IMPL_ADDREF(nsDocumentOpenInfo) @@ -179,7 +196,8 @@ nsDocumentOpenInfo::nsDocumentOpenInfo(nsIInterfaceRequestor* aWindowContext, nsURILoader* aURILoader) : m_originalContext(aWindowContext), mFlags(aFlags), - mURILoader(aURILoader) + mURILoader(aURILoader), + mDataConversionDepthLimit(sConvertDataLimit) { } @@ -625,6 +643,12 @@ nsDocumentOpenInfo::ConvertData(nsIRequest *request, PromiseFlatCString(aSrcContentType).get(), PromiseFlatCString(aOutContentType).get())); + if (mDataConversionDepthLimit == 0) { + LOG(("[0x%p] nsDocumentOpenInfo::ConvertData - reached the recursion limit!", this)); + // This will fall back to external helper app handling. + return NS_ERROR_ABORT; + } + NS_PRECONDITION(aSrcContentType != aOutContentType, "ConvertData called when the two types are the same!"); nsresult rv = NS_OK; @@ -648,6 +672,9 @@ nsDocumentOpenInfo::ConvertData(nsIRequest *request, LOG((" Downstream DocumentOpenInfo would be: 0x%p", nextLink.get())); + // Decrease the conversion recursion limit by one to prevent infinite loops. + nextLink->mDataConversionDepthLimit = mDataConversionDepthLimit - 1; + // Make sure nextLink starts with the contentListener that said it wanted the // results of this decode. nextLink->m_contentListener = aListener; @@ -885,6 +912,9 @@ nsresult nsURILoader::OpenChannel(nsIChannel* channel, } } + static bool once = InitPreferences(); + mozilla::Unused << once; + // we need to create a DocumentOpenInfo object which will go ahead and open // the url and discover the content type.... RefPtr loader =