зеркало из https://github.com/mozilla/gecko-dev.git
Bug 780831 - Guard against plugin code leaking refs in the JNI local ref table. r=snorp
This commit is contained in:
Родитель
2db3b4a113
Коммит
036e2a1541
|
@ -5,6 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/PluginPRLibrary.h"
|
||||
#include "nsPluginSafety.h"
|
||||
// Some plugins on Windows, notably Quake Live, implement NP_Initialize using
|
||||
// cdecl instead of the documented stdcall. In order to work around this,
|
||||
// we force the caller to use a frame pointer.
|
||||
|
@ -39,6 +40,8 @@ PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs,
|
|||
if (!env)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mozilla::AutoLocalJNIFrame jniFrame(env);
|
||||
|
||||
if (mNP_Initialize) {
|
||||
*error = mNP_Initialize(bFuncs, pFuncs, env);
|
||||
} else {
|
||||
|
@ -194,6 +197,8 @@ PluginPRLibrary::NPP_New(NPMIMEType pluginType, NPP instance,
|
|||
{
|
||||
if (!mNPP_New)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
MAIN_THREAD_JNI_REF_GUARD;
|
||||
*error = mNPP_New(pluginType, instance, mode, argc, argn, argv, saved);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -206,6 +211,7 @@ PluginPRLibrary::NPP_ClearSiteData(const char* site, uint64_t flags,
|
|||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
MAIN_THREAD_JNI_REF_GUARD;
|
||||
NPError result = mNPP_ClearSiteData(site, flags, maxAge);
|
||||
|
||||
switch (result) {
|
||||
|
@ -229,6 +235,7 @@ PluginPRLibrary::NPP_GetSitesWithData(InfallibleTArray<nsCString>& result)
|
|||
|
||||
result.Clear();
|
||||
|
||||
MAIN_THREAD_JNI_REF_GUARD;
|
||||
char** sites = mNPP_GetSitesWithData();
|
||||
if (!sites) {
|
||||
return NS_OK;
|
||||
|
|
|
@ -519,19 +519,6 @@ nsNPAPIPluginInstance::Start()
|
|||
// before returning. If the plugin returns failure, we'll clear it out below.
|
||||
mRunning = RUNNING;
|
||||
|
||||
#if MOZ_WIDGET_ANDROID
|
||||
// Flash creates some local JNI references during initialization (NPP_New). It does not
|
||||
// remove these references later, so essentially they are leaked. AutoLocalJNIFrame
|
||||
// prevents this by pushing a JNI frame. As a result, all local references created
|
||||
// by Flash are contained in this frame. AutoLocalJNIFrame pops the frame once we
|
||||
// go out of scope and the local references are deleted, preventing the leak.
|
||||
JNIEnv* env = AndroidBridge::GetJNIEnv();
|
||||
if (!env)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mozilla::AutoLocalJNIFrame frame(env);
|
||||
#endif
|
||||
|
||||
nsresult newResult = library->NPP_New((char*)mimetype, &mNPP, (uint16_t)mode, count, (char**)names, (char**)values, NULL, &error);
|
||||
mInPluginInitCall = oldVal;
|
||||
|
||||
|
@ -690,6 +677,7 @@ nsresult nsNPAPIPluginInstance::HandleEvent(void* event, int16_t* result)
|
|||
#if defined(XP_WIN) || defined(XP_OS2)
|
||||
NS_TRY_SAFE_CALL_RETURN(tmpResult, (*pluginFunctions->event)(&mNPP, event), this);
|
||||
#else
|
||||
MAIN_THREAD_JNI_REF_GUARD;
|
||||
tmpResult = (*pluginFunctions->event)(&mNPP, event);
|
||||
#endif
|
||||
NPP_PLUGIN_LOG(PLUGIN_LOG_NOISY,
|
||||
|
@ -1403,6 +1391,9 @@ PluginTimerCallback(nsITimer *aTimer, void *aClosure)
|
|||
NPP npp = t->npp;
|
||||
uint32_t id = t->id;
|
||||
|
||||
PLUGIN_LOG(PLUGIN_LOG_NOISY, ("nsNPAPIPluginInstance running plugin timer callback this=%p\n", npp->ndata));
|
||||
|
||||
MAIN_THREAD_JNI_REF_GUARD;
|
||||
(*(t->callback))(npp, id);
|
||||
|
||||
// Make sure we still have an instance and the timer is still alive
|
||||
|
|
|
@ -863,6 +863,7 @@ nsNPAPIPluginStreamListener::HandleRedirectNotification(nsIChannel *oldChannel,
|
|||
#if defined(XP_WIN) || defined(XP_OS2)
|
||||
NS_TRY_SAFE_CALL_VOID((*pluginFunctions->urlredirectnotify)(npp, spec.get(), static_cast<int32_t>(status), mNPStreamWrapper->mNPStream.notifyData), mInst);
|
||||
#else
|
||||
MAIN_THREAD_JNI_REF_GUARD;
|
||||
(*pluginFunctions->urlredirectnotify)(npp, spec.get(), static_cast<int32_t>(status), mNPStreamWrapper->mNPStream.notifyData);
|
||||
#endif
|
||||
return true;
|
||||
|
|
|
@ -10,6 +10,16 @@
|
|||
#include "nsPluginHost.h"
|
||||
#include <prinrval.h>
|
||||
|
||||
// On Android, we need to guard against plugin code leaking entries in the local
|
||||
// JNI ref table. See https://bugzilla.mozilla.org/show_bug.cgi?id=780831#c21
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "AndroidBridge.h"
|
||||
|
||||
#define MAIN_THREAD_JNI_REF_GUARD mozilla::AutoLocalJNIFrame jniFrame
|
||||
#else
|
||||
#define MAIN_THREAD_JNI_REF_GUARD
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#define CALL_SAFETY_ON
|
||||
#endif
|
||||
|
@ -32,6 +42,7 @@ PR_END_MACRO
|
|||
|
||||
#define NS_TRY_SAFE_CALL_RETURN(ret, fun, pluginInst) \
|
||||
PR_BEGIN_MACRO \
|
||||
MAIN_THREAD_JNI_REF_GUARD; \
|
||||
PRIntervalTime startTime = NS_NotifyBeginPluginCall(); \
|
||||
if(gSkipPluginSafeCalls) \
|
||||
ret = fun; \
|
||||
|
@ -55,6 +66,7 @@ PR_END_MACRO
|
|||
|
||||
#define NS_TRY_SAFE_CALL_VOID(fun, pluginInst) \
|
||||
PR_BEGIN_MACRO \
|
||||
MAIN_THREAD_JNI_REF_GUARD; \
|
||||
PRIntervalTime startTime = NS_NotifyBeginPluginCall(); \
|
||||
if(gSkipPluginSafeCalls) \
|
||||
fun; \
|
||||
|
@ -79,6 +91,7 @@ PR_END_MACRO
|
|||
|
||||
#define NS_TRY_SAFE_CALL_RETURN(ret, fun, pluginInst) \
|
||||
PR_BEGIN_MACRO \
|
||||
MAIN_THREAD_JNI_REF_GUARD; \
|
||||
PRIntervalTime startTime = NS_NotifyBeginPluginCall(); \
|
||||
ret = fun; \
|
||||
NS_NotifyPluginCall(startTime); \
|
||||
|
@ -86,6 +99,7 @@ PR_END_MACRO
|
|||
|
||||
#define NS_TRY_SAFE_CALL_VOID(fun, pluginInst) \
|
||||
PR_BEGIN_MACRO \
|
||||
MAIN_THREAD_JNI_REF_GUARD; \
|
||||
PRIntervalTime startTime = NS_NotifyBeginPluginCall(); \
|
||||
fun; \
|
||||
NS_NotifyPluginCall(startTime); \
|
||||
|
|
Загрузка…
Ссылка в новой задаче