rpms/nspluginwrapper/devel nspluginwrapper-1.1.8-fix-invalid-RPC-after-NPP_Destroy.patch, NONE, 1.1 nspluginwrapper.spec, 1.70, 1.71
Warren Togami 砥上勇
wtogami at fedoraproject.org
Wed Dec 3 04:06:44 UTC 2008
Author: wtogami
Update of /cvs/pkgs/rpms/nspluginwrapper/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv12276
Modified Files:
nspluginwrapper.spec
Added Files:
nspluginwrapper-1.1.8-fix-invalid-RPC-after-NPP_Destroy.patch
Log Message:
fix-invalid-RPC-after-NPP_Destroy fixes a crasher
nspluginwrapper-1.1.8-fix-invalid-RPC-after-NPP_Destroy.patch:
--- NEW FILE nspluginwrapper-1.1.8-fix-invalid-RPC-after-NPP_Destroy.patch ---
2008-12-02 21:49 Gwenole Beauchesne <gb.public at free.fr>
* src/npw-viewer.c, src/npw-wrapper.c: Fix invalid RPC beyond
NPP_Destroy(). This fixes the following scenario:
Browser: NPP_Destroy()
-> rpc_method_invoke()
Viewer: NPN_InvalidateRect()
-> rpc_method_invoke()
-> rpc_dispatch() pending messages
-> handle_NPP_Destroy()
-> PluginInstance is killed
-> send PluginInstance but it was killed...
Now, with the help of reference counting, we can hold the
PluginInstance. Besides, NPP_Destroy() will reset instance_id,
thus RPC won't be sending a "valid" PluginInstance to the other
side, thus reducing the other side call to a no-op. i.e. don't
try to do anything with the browser NPP instance that was killed
previously (the NPP_Destroy() call would have completed by the
time the browser-side needs to handle incoming RPC).
2008-12-02 21:00 Gwenole Beauchesne <gb.public at free.fr>
* src/npw-viewer.c: Preserve PluginInstance objects during
invoke_NPN_*() function calls. This is because
rpc_method_invoke() can handle pending messages, among which an
NPP_Destroy() is possible. Since the latter unref the
PluginInstance, we could arrive in a situation where we are
dereferencing deallocated data.
2008-12-02 20:44 Gwenole Beauchesne <gb.public at free.fr>
* src/npw-common.h, src/npw-viewer.c, src/npw-wrapper.c: Replace
all RPC_TYPE_NPP with RPC_TYPE_NPW_PLUGIN_INSTANCE.
2008-12-02 20:15 Gwenole Beauchesne <gb.public at free.fr>
* src/npw-rpc.c, src/npw-rpc.h: Add RPC_TYPE_NPW_PLUGIN_INSTANCE
to marshal PluginInstance objects.
2008-12-01 23:01 Gwenole Beauchesne <gb.public at free.fr>
* src/npw-viewer.c: Pass PluginInstance to invoke_NP*() functions.
The next step is to replace RPC_TYPE_NPP with
RPC_TYPE_NPW_PLUGIN_INSTANCE.
2008-12-01 21:55 Gwenole Beauchesne <gb.public at free.fr>
* src/npw-viewer.c, src/npw-wrapper.c: Minor cleanups. Make sure
plugin->instance is NULL on exit from NPP_Destroy().
2008-12-01 21:47 Gwenole Beauchesne <gb.public at free.fr>
* src/npw-common.h: Remove extraneous "extern" linkage keyword,
this is default behaviour.
2008-12-01 21:46 Gwenole Beauchesne <gb.public at free.fr>
* src/npw-common.c, src/npw-common.h, src/npw-viewer.c,
src/npw-wrapper.c: Add infrastructure to refcount PlugInstances.
Index: src/npw-common.h
===================================================================
--- src/npw-common.h (révision 775)
+++ src/npw-common.h (révision 783)
@@ -55,17 +55,47 @@
/* PluginInstance */
#define NPW_DECL_PLUGIN_INSTANCE \
- NPP instance; \
- uint32_t instance_id;
+ NPW_PluginInstanceClass *klass; \
+ uint32_t refcount; \
+ NPP instance; \
+ uint32_t instance_id;
-typedef struct _NPW_PluginInstance NPW_PluginInstance;
+typedef struct _NPW_PluginInstance NPW_PluginInstance;
+typedef struct _NPW_PluginInstanceClass NPW_PluginInstanceClass;
+
struct _NPW_PluginInstance
{
NPW_DECL_PLUGIN_INSTANCE;
};
-#define NPW_PLUGIN_INSTANCE(instance) npw_get_plugin_instance (instance)
+typedef void *
+(*NPW_PluginInstanceAllocateFunctionPtr) (void);
+typedef void
+(*NPW_PluginInstanceDeallocateFunctionPtr) (NPW_PluginInstance *plugin);
+
+typedef void
+(*NPW_PluginInstanceFinalizeFunctionPtr) (NPW_PluginInstance *plugin);
+
+struct _NPW_PluginInstanceClass
+{
+ NPW_PluginInstanceAllocateFunctionPtr allocate;
+ NPW_PluginInstanceDeallocateFunctionPtr deallocate;
+ NPW_PluginInstanceFinalizeFunctionPtr finalize;
+};
+
+void *
+npw_plugin_instance_new(NPW_PluginInstanceClass *klass) attribute_hidden;
+
+void *
+npw_plugin_instance_ref(void *ptr) attribute_hidden;
+
+void
+npw_plugin_instance_unref(void *ptr) attribute_hidden;
+
+#define NPW_PLUGIN_INSTANCE(instance) npw_get_plugin_instance (instance)
+#define NPW_PLUGIN_INSTANCE_NPP(plugin) npw_get_plugin_instance_npp (plugin)
+
static inline NPW_PluginInstance *
_npw_get_plugin_instance (NPP instance)
{
@@ -95,6 +125,12 @@
return NULL;
}
+static inline NPP
+npw_get_plugin_instance_npp (NPW_PluginInstance *plugin)
+{
+ return plugin ? plugin->instance : NULL;
+}
+
/* StreamInstance */
#define NPW_DECL_STREAM_INSTANCE \
NPStream *stream; \
@@ -136,7 +172,7 @@
__func__, __FILE__, __LINE__)
/* Initialize NPAPI hooks */
-extern void
+void
NPW_InitializeFuncs (NPNetscapeFuncs *mozilla_funcs,
NPPluginFuncs *plugin_funcs)
attribute_hidden;
@@ -158,19 +194,19 @@
};
/* Create identifier from an integer */
-extern NPW_Identifier
+NPW_Identifier
NPW_CreateIntIdentifier (int32_t value);
/* Create identifier from a string (that is copied) */
-extern NPW_Identifier
+NPW_Identifier
NPW_CreateStringIdentifier (const char *str);
/* Create identifier from a string (that is now owned by the identifier) */
-extern NPW_Identifier
+NPW_Identifier
NPW_CreateStringIdentifierSink (char *str);
/* Destroy identifier */
-extern void
+void
NPW_DestroyIdentifier (NPW_Identifier id);
/* Check whether identifier is an integer */
Index: src/npw-viewer.c
===================================================================
--- src/npw-viewer.c (révision 775)
+++ src/npw-viewer.c (révision 783)
@@ -79,6 +79,9 @@
#define PLUGIN_INSTANCE(instance) \
((PluginInstance *)NPW_PLUGIN_INSTANCE(instance))
+#define PLUGIN_INSTANCE_NPP(plugin) \
+ NPW_PLUGIN_INSTANCE_NPP((NPW_PluginInstance *)(plugin))
+
// Browser side data for an NPStream instance
typedef struct _StreamInstance {
NPW_DECL_STREAM_INSTANCE;
@@ -103,6 +106,25 @@
/* === Helpers === */
/* ====================================================================== */
+// PluginInstance vfuncs
+static void *plugin_instance_allocate(void);
+static void plugin_instance_deallocate(PluginInstance *plugin);
+
+static NPW_PluginInstanceClass PluginInstanceClass = {
+ (NPW_PluginInstanceAllocateFunctionPtr)plugin_instance_allocate,
+ (NPW_PluginInstanceDeallocateFunctionPtr)plugin_instance_deallocate,
+};
+
+static void *plugin_instance_allocate(void)
+{
+ return NPW_MemNew0(PluginInstance, 1);
+}
+
+static void plugin_instance_deallocate(PluginInstance *plugin)
+{
+ NPW_MemFree(plugin);
[...1951 lines suppressed...]
if (plugin == NULL)
return -1;
@@ -2393,7 +2441,7 @@
int error = rpc_method_invoke(plugin->connection,
RPC_METHOD_NPP_PRINT,
- RPC_TYPE_NPP, plugin->instance,
+ RPC_TYPE_NPW_PLUGIN_INSTANCE, plugin,
RPC_TYPE_UINT32, platform_print_id,
RPC_TYPE_NP_PRINT, PrintInfo,
RPC_TYPE_INVALID);
@@ -2425,6 +2473,7 @@
{
if (instance == NULL)
return;
+
PluginInstance *plugin = PLUGIN_INSTANCE(instance);
if (plugin == NULL)
return;
@@ -2445,7 +2494,7 @@
int error = rpc_method_invoke(plugin->connection,
RPC_METHOD_NPP_HANDLE_EVENT,
- RPC_TYPE_NPP, plugin->instance,
+ RPC_TYPE_NPW_PLUGIN_INSTANCE, plugin,
RPC_TYPE_NP_EVENT, event,
RPC_TYPE_INVALID);
Index: src/npw-rpc.c
===================================================================
--- src/npw-rpc.c (révision 775)
+++ src/npw-rpc.c (révision 783)
@@ -90,22 +90,19 @@
/*
- * Process NPP objects
+ * Process NPW_PluginInstance objects
*/
-static int do_send_NPP(rpc_message_t *message, void *p_value)
+static int do_send_NPW_PluginInstance(rpc_message_t *message, void *p_value)
{
+ NPW_PluginInstance *plugin = (NPW_PluginInstance *)p_value;
uint32_t instance_id = 0;
- NPP instance = (NPP)p_value;
- if (instance) {
- NPW_PluginInstance *plugin = NPW_PLUGIN_INSTANCE(instance);
- if (plugin)
- instance_id = plugin->instance_id;
- }
+ if (plugin)
+ instance_id = plugin->instance_id;
return rpc_message_send_uint32(message, instance_id);
}
-static int do_recv_NPP(rpc_message_t *message, void *p_value)
+static int do_recv_NPW_PluginInstance(rpc_message_t *message, void *p_value)
{
int error;
uint32_t instance_id;
@@ -115,9 +112,35 @@
NPW_PluginInstance *plugin = id_lookup(instance_id);
if (instance_id && plugin == NULL)
- npw_printf("ERROR: passing an unknown instance\n");
- if (plugin && plugin->instance == NULL)
- npw_printf("ERROR: passing a NULL instance through plugin instance id\n");
+ npw_printf("ERROR: no valid NPP -> PluginInstance mapping found\n");
+ else if (plugin && plugin->instance == NULL)
+ npw_printf("ERROR: no valid PluginInstance -> NPP mapping found\n");
+ *((NPW_PluginInstance **)p_value) = plugin;
+ return RPC_ERROR_NO_ERROR;
+}
+
+
+/*
+ * Process NPP objects
+ */
+
+static int do_send_NPP(rpc_message_t *message, void *p_value)
+{
+ NPP instance = (NPP)p_value;
+ NPW_PluginInstance *plugin = NULL;
+ if (instance)
+ plugin = NPW_PLUGIN_INSTANCE(instance);
+ return do_send_NPW_PluginInstance(message, plugin);
+}
+
+static int do_recv_NPP(rpc_message_t *message, void *p_value)
+{
+ int error;
+ NPW_PluginInstance *plugin;
+
+ if ((error = do_recv_NPW_PluginInstance(message, &plugin)) < 0)
+ return error;
+
*((NPP *)p_value) = plugin ? plugin->instance : NULL;
return RPC_ERROR_NO_ERROR;
}
@@ -1476,6 +1499,12 @@
do_recv_NPP
},
{
+ RPC_TYPE_NPW_PLUGIN_INSTANCE,
+ sizeof(NPW_PluginInstance *),
+ do_send_NPW_PluginInstance,
+ do_recv_NPW_PluginInstance
+ },
+ {
RPC_TYPE_NP_STREAM,
sizeof(NPStream *),
do_send_NPStream,
Index: src/npw-common.c
===================================================================
--- src/npw-common.c (révision 775)
+++ src/npw-common.c (révision 783)
@@ -25,6 +25,57 @@
#define DEBUG 0
#include "debug.h"
+
+/* ====================================================================== */
+/* === Plugin instances === */
+/* ====================================================================== */
+
+void *
+npw_plugin_instance_new(NPW_PluginInstanceClass *klass)
+{
+ NPW_PluginInstance *plugin;
+ if (klass && klass->allocate)
+ plugin = klass->allocate ();
+ else
+ plugin = NPW_MemNew0 (NPW_PluginInstance, 1);
+ if (plugin)
+ {
+ plugin->klass = klass;
+ plugin->refcount = 1;
+ }
+ return plugin;
+}
+
+void *
+npw_plugin_instance_ref(void *ptr)
+{
+ NPW_PluginInstance *plugin = (NPW_PluginInstance *)ptr;
+ if (plugin)
+ plugin->refcount++;
+ return plugin;
+}
+
+void
+npw_plugin_instance_unref(void *ptr)
+{
+ NPW_PluginInstance *plugin = (NPW_PluginInstance *)ptr;
+ if (plugin == NULL)
+ return;
+ if (--plugin->refcount > 0)
+ return;
+ NPW_PluginInstanceClass *klass = plugin->klass;
+ if (klass && klass->finalize)
+ klass->finalize (plugin);
+ if (klass && klass->deallocate)
+ klass->deallocate (plugin);
+ else
+ NPW_MemFree (plugin);
+}
+
+/* ====================================================================== */
+/* === NPAPI interface === */
+/* ====================================================================== */
+
static NPNetscapeFuncs g_mozilla_funcs;
static NPPluginFuncs g_plugin_funcs;
@@ -38,10 +89,6 @@
MIN (sizeof (g_plugin_funcs), plugin_funcs->size));
}
-/* ====================================================================== */
-/* === NPAPI interface === */
-/* ====================================================================== */
-
void *
NPN_MemAlloc (uint32_t size)
{
Index: src/npw-rpc.h
===================================================================
--- src/npw-rpc.h (révision 775)
+++ src/npw-rpc.h (révision 783)
@@ -115,7 +115,8 @@
RPC_TYPE_NP_IDENTIFIER,
RPC_TYPE_NP_STRING, /* 15 */
RPC_TYPE_NP_VARIANT,
- RPC_TYPE_NP_UTF8
+ RPC_TYPE_NP_UTF8,
+ RPC_TYPE_NPW_PLUGIN_INSTANCE
};
// NPPrintData is used to get the plugin printed tmpfile
Index: nspluginwrapper.spec
===================================================================
RCS file: /cvs/pkgs/rpms/nspluginwrapper/devel/nspluginwrapper.spec,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -r1.70 -r1.71
--- nspluginwrapper.spec 1 Dec 2008 15:24:07 -0000 1.70
+++ nspluginwrapper.spec 3 Dec 2008 04:06:14 -0000 1.71
@@ -65,7 +65,7 @@
Summary: A compatibility layer for Netscape 4 plugins
Name: nspluginwrapper
Version: 1.1.8
-Release: 1%{?dist}
+Release: 2%{?dist}
Source0: %{name}-%{version}%{?svndate:-%{svndate}}.tar.bz2
Source1: %{plugin_config_name}.tar.gz
Source2: plugin-config.sh.in
@@ -74,6 +74,7 @@
Patch2: nspluginwrapper-1.1.4-configure.patch
Patch3: nspluginwrapper-1.1.8-directory.patch
Patch10: nspluginwrapper-1.1.2-event.patch
+Patch11: nspluginwrapper-1.1.8-fix-invalid-RPC-after-NPP_Destroy.patch
Patch100: plugin-config-setuid.patch
Patch101: plugin-config-umask.patch
Patch102: plugin-config-print.patch
@@ -108,6 +109,7 @@
# Package fixes
%patch10 -p1 -b .event
+%patch11 -p0 -b .invalid-RPC
# Plugin-config patches
pushd %plugin_config_name
@@ -232,6 +234,9 @@
%config %{_sysconfdir}/sysconfig/%{name}
%changelog
+* Tue Dec 02 2008 Warren Togami <wtogami at redhat.com> 1.1.8-2
+- fix-invalid-RPC-after-NPP_Destroy fixes a crasher
+
* Mon Dec 1 2008 Martin Stransky <stransky at redhat.com> 1.1.8-1
- Updated to 1.1.8
- Removed already upstreamed patches
More information about the fedora-extras-commits
mailing list