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