Bug 1377614 - Part 2 - System extensions fail to load on Mac and Linux local builds. r=jimm

On Mac and Linux, allow unpacked extension resources to load from outside the extension directory if they're in the repo.

MozReview-Commit-ID: 1xsKV72aUJx

--HG--
extra : rebase_source : 1adefb0977e63935366a45dbf7c471d868655838
This commit is contained in:
Haik Aftandilian 2017-07-05 14:11:48 -07:00
Родитель 84f7ba492b
Коммит 5d3493e27d
2 изменённых файлов: 74 добавлений и 0 удалений

Просмотреть файл

@ -43,6 +43,10 @@
#include "nsILocalFileWin.h"
#endif
#if !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
#include "mozilla/SandboxSettings.h"
#endif
#define EXTENSION_SCHEME "moz-extension"
using mozilla::ipc::FileDescriptor;
using OptionalIPCStream = mozilla::ipc::OptionalIPCStream;
@ -344,6 +348,9 @@ ExtensionProtocolHandler::GetSingleton()
ExtensionProtocolHandler::ExtensionProtocolHandler()
: SubstitutingProtocolHandler(EXTENSION_SCHEME)
#if !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
, mAlreadyCheckedDevRepo(false)
#endif
{
mUseRemoteFileChannels = IsNeckoChild() &&
Preferences::GetBool("extensions.webextensions.protocol.remote");
@ -498,6 +505,39 @@ ExtensionProtocolHandler::SubstituteChannel(nsIURI* aURI,
return NS_OK;
}
#if !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
// The |aRequestedFile| argument must already be Normalize()'d
Result<Ok, nsresult>
ExtensionProtocolHandler::DevRepoContains(nsIFile* aRequestedFile,
bool *aResult)
{
MOZ_ASSERT(!IsNeckoChild());
MOZ_ASSERT(aResult);
*aResult = false;
// On the first invocation, set mDevRepo if this is a
// development build with MOZ_DEVELOPER_REPO_DIR set.
if (!mAlreadyCheckedDevRepo) {
mAlreadyCheckedDevRepo = true;
if (mozilla::IsDevelopmentBuild()) {
char *developer_repo_dir = PR_GetEnv("MOZ_DEVELOPER_REPO_DIR");
if (developer_repo_dir) {
NS_TRY(NS_NewLocalFile(NS_ConvertUTF8toUTF16(developer_repo_dir),
false, getter_AddRefs(mDevRepo)));
NS_TRY(mDevRepo->Normalize());
}
}
}
if (mDevRepo) {
// This is a development build
NS_TRY(mDevRepo->Contains(aRequestedFile, aResult));
}
return Ok();
}
#endif /* !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) */
Result<nsCOMPtr<nsIInputStream>, nsresult>
ExtensionProtocolHandler::NewStream(nsIURI* aChildURI,
nsILoadInfo* aChildLoadInfo,
@ -584,7 +624,17 @@ ExtensionProtocolHandler::NewStream(nsIURI* aChildURI,
bool isResourceFromExtensionDir = false;
NS_TRY(extensionDir->Contains(requestedFile, &isResourceFromExtensionDir));
if (!isResourceFromExtensionDir) {
#if defined(XP_WIN)
return Err(NS_ERROR_FILE_ACCESS_DENIED);
#elif defined(MOZ_CONTENT_SANDBOX)
// On a dev build, we allow an unpacked resource that isn't
// from the extension directory as long as it is from the repo.
bool isResourceFromDevRepo = false;
MOZ_TRY(DevRepoContains(requestedFile, &isResourceFromDevRepo));
if (!isResourceFromDevRepo) {
return Err(NS_ERROR_FILE_ACCESS_DENIED);
}
#endif /* defined(XP_WIN) */
}
nsCOMPtr<nsIInputStream> inputStream;

Просмотреть файл

@ -148,6 +148,30 @@ private:
nsACString& aResolvedSpec,
nsIChannel** aRetVal);
#if !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
/**
* Sets the aResult outparam to true if we are a developer build with the
* repo dir environment variable set and the requested file resides in the
* repo dir. Developer builds may load system extensions with web-accessible
* resources that are symlinks to files in the repo dir. This method is for
* checking if an unpacked resource requested by the child is from the repo.
* The requested file must be already Normalized().
*
* @param aRequestedFile the requested web-accessible resource file. Argument
* must be an nsIFile for which Normalize() has already been called.
* @param aResult outparam set to true on development builds when the
* requested file resides in the repo
*/
Result<Ok, nsresult> DevRepoContains(nsIFile* aRequestedFile, bool *aResult);
// On development builds, this points to development repo. Lazily set.
nsCOMPtr<nsIFile> mDevRepo;
// Set to true once we've already tried to load the dev repo path,
// allowing for lazy initialization of |mDevRepo|.
bool mAlreadyCheckedDevRepo;
#endif /* !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) */
// Used for opening JAR files off the main thread when we just need to
// obtain a file descriptor to send back to the child.
RefPtr<mozilla::LazyIdleThread> mFileOpenerThread;