Bug 558184 - Part 9 - Optionally load a script in a sandbox in the content process for every plugin instance. r=bz.

--HG--
extra : rebase_source : 7d967d0bfd08ca1bbd3928f95a2a8e42c6e9600c
extra : source : f2d9aadaa14ea115518e005bebe6f04cfba50424
This commit is contained in:
Peter Van der Beken 2016-09-27 18:28:36 +08:00
parent 2310b3bd39
commit 6c1bf2eef6
7 changed files with 82 additions and 7 deletions

View File

@ -2404,6 +2404,42 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
break;
}
nsString sandboxScript;
tag->GetSandboxScript(sandboxScript);
if (!sandboxScript.IsEmpty()) {
// Create a sandbox.
AutoJSAPI jsapi;
jsapi.Init();
JS::Rooted<JSObject*> sandbox(jsapi.cx());
rv = nsContentUtils::XPConnect()->
CreateSandbox(jsapi.cx(), nsContentUtils::GetSystemPrincipal(),
sandbox.address());
if (NS_FAILED(rv)) {
break;
}
AutoEntryScript aes(sandbox, "JS plugin sandbox code");
JS::Rooted<JS::Value> element(aes.cx());
if (!ToJSValue(aes.cx(), thisContent, &element)) {
rv = NS_ERROR_FAILURE;
break;
}
if (!JS_DefineProperty(aes.cx(), sandbox, "pluginElement", element, JSPROP_ENUMERATE)) {
rv = NS_ERROR_FAILURE;
break;
}
JS::Rooted<JS::Value> rval(aes.cx());
// If the eval'ed code throws we won't load and do fallback instead.
rv = nsContentUtils::XPConnect()->EvalInSandboxObject(sandboxScript, nullptr, aes.cx(), sandbox, &rval);
if (NS_FAILED(rv)) {
break;
}
}
nsCOMPtr<nsIURI> handlerURI;
if (tag) {
tag->GetHandlerURI(getter_AddRefs(handlerURI));

View File

@ -69,11 +69,23 @@ interface nsIPluginTag : nsISupports
[scriptable, uuid(6d22c968-226d-4156-b230-da6ad6bbf6e8)]
interface nsIFakePluginTag : nsIPluginTag
{
// The URI that should be loaded into the tag (as a frame) to handle the
// plugin. Note that the original data/src value for the plugin is not loaded
// and will need to be requested by the handler via XHR or similar if desired.
/**
* The URI that should be loaded into the tag (as a frame) to handle the
* plugin. Note that the original data/src value for the plugin is not loaded
* and will need to be requested by the handler via XHR or similar if desired.
*/
readonly attribute nsIURI handlerURI;
/**
* Optional script to run in a sandbox when instantiating a plugin. If this
* value is an empty string then no such script will be run.
* The script runs in a sandbox with system principal in the process that
* contains the element that instantiates the plugin (ie the EMBED or OBJECT
* element). The sandbox global has a 'pluginElement' property that the script
* can use to access the element that instantiates the plugin.
*/
readonly attribute AString sandboxScript;
/**
* A unique id for this JS-implemented plugin. 0 is a valid id.
*/

View File

@ -2342,7 +2342,8 @@ nsPluginHost::FindPluginsInContent(bool aCreatePluginList, bool* aPluginsChanged
tag.mimeTypes(),
tag.mimeDescriptions(),
tag.extensions(),
tag.niceName()));
tag.niceName(),
tag.sandboxScript()));
}
}
@ -2541,7 +2542,8 @@ nsPluginHost::FindPluginsForContent(uint32_t aPluginEpoch,
tag->MimeTypes(),
tag->MimeDescriptions(),
tag->Extensions(),
tag->GetNiceFileName()));
tag->GetNiceFileName(),
tag->SandboxScript()));
continue;
}

View File

@ -833,12 +833,14 @@ nsFakePluginTag::nsFakePluginTag(uint32_t aId,
const nsTArray<nsCString>& aMimeTypes,
const nsTArray<nsCString>& aMimeDescriptions,
const nsTArray<nsCString>& aExtensions,
const nsCString& aNiceName)
const nsCString& aNiceName,
const nsString& aSandboxScript)
: nsIInternalPluginTag(aName, aDescription, nullptr, nullptr,
aMimeTypes, aMimeDescriptions, aExtensions),
mId(aId),
mHandlerURI(aHandlerURI),
mNiceName(aNiceName),
mSandboxScript(aSandboxScript),
mState(nsPluginTag::ePluginState_Enabled)
{}
@ -878,6 +880,7 @@ nsFakePluginTag::Create(const FakePluginTagInit& aInitDictionary,
CopyUTF16toUTF8(aInitDictionary.mDescription, tag->mDescription);
CopyUTF16toUTF8(aInitDictionary.mFileName, tag->mFileName);
CopyUTF16toUTF8(aInitDictionary.mVersion, tag->mVersion);
tag->mSandboxScript = aInitDictionary.mSandboxScript;
for (const FakePluginMimeEntry& mimeEntry : aInitDictionary.mMimeEntries) {
CopyUTF16toUTF8(mimeEntry.mType, *tag->mMimeTypes.AppendElement());
@ -904,6 +907,13 @@ nsFakePluginTag::GetHandlerURI(nsIURI **aResult)
return NS_OK;
}
NS_IMETHODIMP
nsFakePluginTag::GetSandboxScript(nsAString& aSandboxScript)
{
aSandboxScript = mSandboxScript;
return NS_OK;
}
NS_IMETHODIMP
nsFakePluginTag::GetDescription(/* utf-8 */ nsACString& aResult)
{

View File

@ -218,7 +218,8 @@ public:
const nsTArray<nsCString>& aMimeTypes,
const nsTArray<nsCString>& aMimeDescriptions,
const nsTArray<nsCString>& aExtensions,
const nsCString& aNiceName);
const nsCString& aNiceName,
const nsString& aSandboxScript);
bool IsEnabled() override;
const nsCString& GetNiceFileName() override;
@ -229,6 +230,8 @@ public:
uint32_t Id() const { return mId; }
const nsString& SandboxScript() const { return mSandboxScript; }
static const int32_t NOT_JSPLUGIN = -1;
private:
@ -249,6 +252,8 @@ private:
nsCString mFullPath;
nsCString mNiceName;
nsString mSandboxScript;
nsPluginTag::PluginState mState;
// Stores the id to use for the JS-implemented plugin that gets registered

View File

@ -37,6 +37,7 @@ struct FakePluginTag
nsCString[] mimeDescriptions;
nsCString[] extensions;
nsCString niceName;
nsString sandboxScript;
};
union PluginIdentifier

View File

@ -26,6 +26,15 @@ dictionary FakePluginTagInit {
DOMString description = "";
DOMString fileName = "";
DOMString version = "";
/**
* Optional script to run in a sandbox when instantiating a plugin. The script
* runs in a sandbox with system principal in the process that contains the
* element that instantiates the plugin (ie the EMBED or OBJECT element). The
* sandbox global has a 'pluginElement' property that the script can use to
* access the element that instantiates the plugin.
*/
DOMString sandboxScript = "";
};
/**