aboutsummaryrefslogtreecommitdiffstats
path: root/src/libstrongswan/plugins/plugin_loader.c
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2017-05-23 18:33:00 +0200
committerTobias Brunner <tobias@strongswan.org>2017-05-23 18:38:46 +0200
commit4cc77142e0292d5d00f20e62849139f4401895c8 (patch)
treed19d858f3f27791781a879703951b9218f0c179f /src/libstrongswan/plugins/plugin_loader.c
parent4d0795bcefeb7d6156fda9b59e75a7dbe05de6e5 (diff)
parenta9b698f5be2519353d91cd6be52b97ce7f5d6fe6 (diff)
downloadstrongswan-4cc77142e0292d5d00f20e62849139f4401895c8.tar.bz2
strongswan-4cc77142e0292d5d00f20e62849139f4401895c8.tar.xz
Merge branch 'fuzzing'
Adds support for fuzzing the certificate parser provided by the default plugins (x509, pem, gmp etc.) on Google's OSS-Fuzz infrastructure (or generally with libFuzzer). Fixes several issues that were found while fuzzing these plugins. When building the libraries monolithically and statically the plugin constructors are now hard-coded in each library so the plugin code is not removed by the linker because it thinks none of their symbols are ever referenced.
Diffstat (limited to 'src/libstrongswan/plugins/plugin_loader.c')
-rw-r--r--src/libstrongswan/plugins/plugin_loader.c85
1 files changed, 78 insertions, 7 deletions
diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c
index e4698fac0..4daf3f13e 100644
--- a/src/libstrongswan/plugins/plugin_loader.c
+++ b/src/libstrongswan/plugins/plugin_loader.c
@@ -40,6 +40,13 @@ typedef struct registered_feature_t registered_feature_t;
typedef struct provided_feature_t provided_feature_t;
typedef struct plugin_entry_t plugin_entry_t;
+#ifdef STATIC_PLUGIN_CONSTRUCTORS
+/**
+ * Statically registered constructors
+ */
+static hashtable_t *plugin_constructors = NULL;
+#endif
+
/**
* private data of plugin_loader
*/
@@ -298,6 +305,46 @@ static plugin_t *static_features_create(const char *name,
return &this->public;
}
+#ifdef STATIC_PLUGIN_CONSTRUCTORS
+/*
+ * Described in header.
+ */
+void plugin_constructor_register(char *name, void *constructor)
+{
+ bool old = FALSE;
+
+ if (lib && lib->leak_detective)
+ {
+ old = lib->leak_detective->set_state(lib->leak_detective, FALSE);
+ }
+
+ if (!plugin_constructors)
+ {
+ chunk_hash_seed();
+ plugin_constructors = hashtable_create(hashtable_hash_str,
+ hashtable_equals_str, 32);
+ }
+ if (constructor)
+ {
+ plugin_constructors->put(plugin_constructors, name, constructor);
+ }
+ else
+ {
+ plugin_constructors->remove(plugin_constructors, name);
+ if (!plugin_constructors->get_count(plugin_constructors))
+ {
+ plugin_constructors->destroy(plugin_constructors);
+ plugin_constructors = NULL;
+ }
+ }
+
+ if (lib && lib->leak_detective)
+ {
+ lib->leak_detective->set_state(lib->leak_detective, old);
+ }
+}
+#endif
+
/**
* create a plugin
* returns: NOT_FOUND, if the constructor was not found
@@ -309,7 +356,7 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle,
{
char create[128];
plugin_t *plugin;
- plugin_constructor_t constructor;
+ plugin_constructor_t constructor = NULL;
if (snprintf(create, sizeof(create), "%s_plugin_create",
name) >= sizeof(create))
@@ -317,8 +364,17 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle,
return FAILED;
}
translate(create, "-", "_");
- constructor = dlsym(handle, create);
- if (constructor == NULL)
+#ifdef STATIC_PLUGIN_CONSTRUCTORS
+ if (plugin_constructors)
+ {
+ constructor = plugin_constructors->get(plugin_constructors, name);
+ }
+ if (!constructor)
+#endif
+ {
+ constructor = dlsym(handle, create);
+ }
+ if (!constructor)
{
return NOT_FOUND;
}
@@ -674,9 +730,11 @@ static bool load_dependencies(private_plugin_loader_t *this,
if (!find_compatible_feature(this, &provided->feature[i]))
{
- char *name, *provide, *depend;
bool soft = provided->feature[i].kind == FEATURE_SDEPEND;
+#ifndef USE_FUZZING
+ char *name, *provide, *depend;
+
name = provided->entry->plugin->get_name(provided->entry->plugin);
provide = plugin_feature_get_string(&provided->feature[0]);
depend = plugin_feature_get_string(&provided->feature[i]);
@@ -697,6 +755,8 @@ static bool load_dependencies(private_plugin_loader_t *this,
}
free(provide);
free(depend);
+#endif /* !USE_FUZZING */
+
if (soft)
{ /* it's ok if we can't resolve soft dependencies */
continue;
@@ -716,8 +776,6 @@ static void load_feature(private_plugin_loader_t *this,
{
if (load_dependencies(this, provided, level))
{
- char *name, *provide;
-
if (plugin_feature_load(provided->entry->plugin, provided->feature,
provided->reg))
{
@@ -727,6 +785,9 @@ static void load_feature(private_plugin_loader_t *this,
return;
}
+#ifndef USE_FUZZING
+ char *name, *provide;
+
name = provided->entry->plugin->get_name(provided->entry->plugin);
provide = plugin_feature_get_string(&provided->feature[0]);
if (provided->entry->critical)
@@ -740,6 +801,7 @@ static void load_feature(private_plugin_loader_t *this,
provide, name);
}
free(provide);
+#endif /* !USE_FUZZING */
}
else
{ /* TODO: we could check the current level and set a different flag when
@@ -759,13 +821,16 @@ static void load_provided(private_plugin_loader_t *this,
provided_feature_t *provided,
int level)
{
- char *name, *provide;
int indent = level * 2;
if (provided->loaded || provided->failed)
{
return;
}
+
+#ifndef USE_FUZZING
+ char *name, *provide;
+
name = provided->entry->plugin->get_name(provided->entry->plugin);
provide = plugin_feature_get_string(provided->feature);
if (provided->loading)
@@ -778,6 +843,12 @@ static void load_provided(private_plugin_loader_t *this,
DBG3(DBG_LIB, "%*sloading feature %s in plugin '%s'",
indent, "", provide, name);
free(provide);
+#else
+ if (provided->loading)
+ {
+ return;
+ }
+#endif /* USE_FUZZING */
provided->loading = TRUE;
load_feature(this, provided, level + 1);