[libpeas] Load C plugins with local linkage
- From: Garrett Regier <gregier src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libpeas] Load C plugins with local linkage
- Date: Thu, 18 Dec 2014 14:14:30 +0000 (UTC)
commit 3ee92ca98b095bbd840f4c7b10df8939fe246484
Author: Thomas Martitz <kugel rockbox org>
Date: Thu Dec 18 05:03:30 2014 -0800
Load C plugins with local linkage
C extensions can bring arbitrary symbols into the global symbol table
which is then shared with all other extensions and the main binary.
This is a recipe for symbol clashes which are hard to debug. Using
G_MODULE_BIND_LOCAL provides proper isolation and makes
applications more robust.
Based on a patch by Thomas Martitz
https://bugzilla.gnome.org/show_bug.cgi?id=740823
docs/reference/libpeas-sections.txt | 1 +
libpeas/peas-engine.c | 6 +++-
libpeas/peas-object-module.c | 62 ++++++++++++++++++++++++++++++++--
libpeas/peas-object-module.h | 4 ++
libpeas/peas-plugin-loader-c.c | 8 +++--
5 files changed, 73 insertions(+), 8 deletions(-)
---
diff --git a/docs/reference/libpeas-sections.txt b/docs/reference/libpeas-sections.txt
index 173777d..ff80d31 100644
--- a/docs/reference/libpeas-sections.txt
+++ b/docs/reference/libpeas-sections.txt
@@ -151,6 +151,7 @@ PEAS_OBJECT_MODULE_GET_CLASS
<SUBSECTION Private>
PeasObjectModulePrivate
peas_object_module_new
+peas_object_module_new_full
peas_object_module_create_object
peas_object_module_get_library
peas_object_module_get_module_name
diff --git a/libpeas/peas-engine.c b/libpeas/peas-engine.c
index 11a3774..7934adc 100644
--- a/libpeas/peas-engine.c
+++ b/libpeas/peas-engine.c
@@ -642,7 +642,11 @@ load_module (const gchar *module_name,
{
PeasObjectModule *module;
- module = peas_object_module_new (module_name, module_dir, TRUE);
+ /* Bind loaders globally, binding
+ * locally can break the plugin loaders
+ */
+ module = peas_object_module_new_full (module_name, module_dir,
+ TRUE, FALSE);
if (!g_type_module_use (G_TYPE_MODULE (module)))
g_clear_object (&module);
diff --git a/libpeas/peas-object-module.c b/libpeas/peas-object-module.c
index c74152e..b556575 100644
--- a/libpeas/peas-object-module.c
+++ b/libpeas/peas-object-module.c
@@ -51,6 +51,7 @@ enum {
PROP_MODULE_NAME,
PROP_PATH,
PROP_RESIDENT,
+ PROP_LOCAL_LINKAGE,
N_PROPERTIES
};
@@ -73,14 +74,19 @@ struct _PeasObjectModulePrivate {
gchar *module_name;
guint resident : 1;
+ guint local_linkage : 1;
};
static gboolean
peas_object_module_load (GTypeModule *gmodule)
{
PeasObjectModule *module = PEAS_OBJECT_MODULE (gmodule);
+ GModuleFlags flags = 0;
gchar *path;
+ if (module->priv->local_linkage)
+ flags = G_MODULE_BIND_LOCAL;
+
path = g_module_build_path (module->priv->path, module->priv->module_name);
g_return_val_if_fail (path != NULL, FALSE);
@@ -92,10 +98,8 @@ peas_object_module_load (GTypeModule *gmodule)
if (G_MODULE_SUFFIX[0] != '\0' && g_str_has_suffix (path, "." G_MODULE_SUFFIX))
path[strlen (path) - strlen (G_MODULE_SUFFIX) - 1] = '\0';
- /* Bind symbols globally and immediately,
- * binding locally broke the Python plugin loader.
- */
- module->priv->library = g_module_open (path, 0);
+ /* Bind symbols immediately to avoid errors long after loading */
+ module->priv->library = g_module_open (path, flags);
g_free (path);
if (module->priv->library == NULL)
@@ -195,6 +199,9 @@ peas_object_module_get_property (GObject *object,
case PROP_RESIDENT:
g_value_set_boolean (value, module->priv->resident);
break;
+ case PROP_LOCAL_LINKAGE:
+ g_value_set_boolean (value, module->priv->local_linkage);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -222,6 +229,9 @@ peas_object_module_set_property (GObject *object,
case PROP_RESIDENT:
module->priv->resident = g_value_get_boolean (value);
break;
+ case PROP_LOCAL_LINKAGE:
+ module->priv->local_linkage = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -268,6 +278,23 @@ peas_object_module_class_init (PeasObjectModuleClass *klass)
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
+ /**
+ * PeasObjectModule:local-linkage
+ *
+ * This property indicates whether the module is loaded with
+ * local linkage, i.e. #G_MODULE_BIND_LOCAL.
+ *
+ * Since 1.14
+ */
+ properties[PROP_LOCAL_LINKAGE] =
+ g_param_spec_boolean ("local-linkage",
+ "Local linkage",
+ "Whether the module loaded with local linkage",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
g_type_class_add_private (klass, sizeof (PeasObjectModulePrivate));
}
@@ -295,6 +322,33 @@ peas_object_module_new (const gchar *module_name,
}
/**
+ * peas_object_module_new_full: (skip)
+ * @module_name: The module name.
+ * @path: The path.
+ * @resident: If the module should be resident.
+ * @local_linkage: Whether to load the module with local linkage.
+ *
+ * Creates a new #PeasObjectModule with local linkage.
+ *
+ * Return value: a new #PeasObjectModule.
+ *
+ * Since 1.14
+ */
+PeasObjectModule *
+peas_object_module_new_full (const gchar *module_name,
+ const gchar *path,
+ gboolean resident,
+ gboolean local_linkage)
+{
+ return PEAS_OBJECT_MODULE (g_object_new (PEAS_TYPE_OBJECT_MODULE,
+ "module-name", module_name,
+ "path", path,
+ "resident", resident,
+ "local-linkage", local_linkage,
+ NULL));
+}
+
+/**
* peas_object_module_create_object: (skip)
* @module: A #PeasObjectModule.
* @interface: The #GType of the extension interface.
diff --git a/libpeas/peas-object-module.h b/libpeas/peas-object-module.h
index 9cd599e..7ddf4f6 100644
--- a/libpeas/peas-object-module.h
+++ b/libpeas/peas-object-module.h
@@ -87,6 +87,10 @@ GType peas_object_module_get_type (void) G_GNUC_CONS
PeasObjectModule *peas_object_module_new (const gchar *module_name,
const gchar *path,
gboolean resident);
+PeasObjectModule *peas_object_module_new_full (const gchar *module_name,
+ const gchar *path,
+ gboolean resident,
+ gboolean local_linkage);
GObject *peas_object_module_create_object (PeasObjectModule *module,
GType interface,
diff --git a/libpeas/peas-plugin-loader-c.c b/libpeas/peas-plugin-loader-c.c
index 1ac9266..b0e8417 100644
--- a/libpeas/peas-plugin-loader-c.c
+++ b/libpeas/peas-plugin-loader-c.c
@@ -60,10 +60,12 @@ peas_plugin_loader_c_load (PeasPluginLoader *loader,
module_dir = peas_plugin_info_get_module_dir (info);
/* Force all C modules to be resident in case they
- * use libraries that do not deal well with reloading
+ * use libraries that do not deal well with reloading.
+ * Furthermore, we use local linkage to improve module isolation.
*/
- info->loader_data = peas_object_module_new (module_name,
- module_dir, TRUE);
+ info->loader_data = peas_object_module_new_full (module_name,
+ module_dir,
+ TRUE, TRUE);
if (!g_type_module_use (G_TYPE_MODULE (info->loader_data)))
g_clear_object (&info->loader_data);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]