Hello,

the attached patch is an extended version of [0], as at the time I
didn't realize that e.g. re:claimID also loads plugins the same way.

As explained both in the linked discussion and in the commit message,
when the ProjectData structure is not GNUnet's default one (i.e. any
third-party application not included in GNUnet's distribution) the
lazy-loading of plugins will search for them in the application's paths
instead of GNUnet's.

This patch only affects the parts using `GNUNET_PLUGIN_load_all', so
those functions using `GNUNET_PLUGIN_load' are still affected by the
bug; however, a quick search shows that the latter function is used in
places that, under normal circumstances, do not interact with the
application's ProjectData (for example, TRANSPORT or ATS startup), so
there shouldn't be any immediate issue.

Thanks,
A.V.

[0] https://lists.gnu.org/archive/html/gnunet-developers/2020-07/msg00049.html

>From b1255303796c1fbe971b08251e05ab4c28349b28 Mon Sep 17 00:00:00 2001
From: Alessio Vanni <[email protected]>
Date: Sun, 13 Dec 2020 15:20:38 +0100
Subject: [PATCH] Add macro to load plugins within GNUnet's context

When `GNUNET_OS_init' is called to change the application project data,
lazy-loading plugins will fail as it will not find the requested files.

The macro will temporarily swap the project data with GNUnet's default one and
search for plugins within GNUnet's installation directory tree.

Applications can still use `GNUNET_PLUGIN_load_all' to load their plugins from
within their installation directory tree.
---
 src/block/block.c                |  8 ++++----
 src/gnsrecord/gnsrecord.c        | 10 ++--------
 src/include/gnunet_plugin_lib.h  | 26 ++++++++++++++++++++++++++
 src/reclaim/reclaim_attribute.c  |  8 ++++----
 src/reclaim/reclaim_credential.c |  8 ++++----
 src/rest/gnunet-rest-server.c    |  8 ++++----
 6 files changed, 44 insertions(+), 24 deletions(-)

diff --git a/src/block/block.c b/src/block/block.c
index 5abe64e69..85475bc5a 100644
--- a/src/block/block.c
+++ b/src/block/block.c
@@ -134,10 +134,10 @@ GNUNET_BLOCK_context_create (const struct GNUNET_CONFIGURATION_Handle *cfg)
 
   ctx = GNUNET_new (struct GNUNET_BLOCK_Context);
   ctx->cfg = cfg;
-  GNUNET_PLUGIN_load_all ("libgnunet_plugin_block_",
-                          (void *) cfg,
-                          &add_plugin,
-                          ctx);
+  GNUNET_PLUGIN_load_all_default ("libgnunet_plugin_block_",
+                                  (void *) cfg,
+                                  &add_plugin,
+                                  ctx);
   return ctx;
 }
 
diff --git a/src/gnsrecord/gnsrecord.c b/src/gnsrecord/gnsrecord.c
index 8d5a6d95b..3c149e22a 100644
--- a/src/gnsrecord/gnsrecord.c
+++ b/src/gnsrecord/gnsrecord.c
@@ -102,15 +102,9 @@ init ()
   if (1 == once)
     return;
   once = 1;
-  const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
-  const struct GNUNET_OS_ProjectData *dpd = GNUNET_OS_project_data_default ();
 
-  if (pd != dpd)
-    GNUNET_OS_init (dpd);
-  GNUNET_PLUGIN_load_all ("libgnunet_plugin_gnsrecord_", NULL,
-                          &add_plugin, NULL);
-  if (pd != dpd)
-    GNUNET_OS_init (pd);
+  GNUNET_PLUGIN_load_all_default ("libgnunet_plugin_gnsrecord_", NULL,
+                                  &add_plugin, NULL);
 }
 
 
diff --git a/src/include/gnunet_plugin_lib.h b/src/include/gnunet_plugin_lib.h
index ffffcab8b..c37bb1124 100644
--- a/src/include/gnunet_plugin_lib.h
+++ b/src/include/gnunet_plugin_lib.h
@@ -121,6 +121,32 @@ GNUNET_PLUGIN_load_all (const char *basename,
                         void *cb_cls);
 
 
+/**
+ * Like #GNUNET_PLUGIN_load_all, but the plugins will always be searched
+ * within GNUnet's directory tree.
+ *
+ * This macro is only useful within GNUnet itself, unless your application
+ * needs to access the raw plugin instead of using GNUnet's APIs.
+ *
+ * @param basename basename of the plugins to load
+ * @param arg argument to the plugin initialization function
+ * @param cb function to call for each plugin found
+ * @param cb_cls closure for @a cb
+ */
+#define GNUNET_PLUGIN_load_all_default(basename, arg, cb, cb_cls)       \
+  do {                                                                  \
+    const struct GNUNET_OS_ProjectData *pd =                            \
+      GNUNET_OS_project_data_get ();                                    \
+    const struct GNUNET_OS_ProjectData *dpd =                           \
+      GNUNET_OS_project_data_default ();                                \
+    if (pd != dpd)                                                      \
+      GNUNET_OS_init (dpd);                                             \
+    GNUNET_PLUGIN_load_all (basename, arg, cb, cb_cls);                 \
+    if (pd != dpd)                                                      \
+      GNUNET_OS_init (pd);                                              \
+  } while (0)
+
+
 /**
  * Unload plugin (runs the "done" callback and returns whatever "done"
  * returned).  The plugin is then unloaded.
diff --git a/src/reclaim/reclaim_attribute.c b/src/reclaim/reclaim_attribute.c
index 2217987ac..29d403b8c 100644
--- a/src/reclaim/reclaim_attribute.c
+++ b/src/reclaim/reclaim_attribute.c
@@ -96,10 +96,10 @@ init ()
   if (GNUNET_YES == initialized)
     return;
   initialized = GNUNET_YES;
-  GNUNET_PLUGIN_load_all ("libgnunet_plugin_reclaim_attribute_",
-                          NULL,
-                          &add_plugin,
-                          NULL);
+  GNUNET_PLUGIN_load_all_default ("libgnunet_plugin_reclaim_attribute_",
+                                  NULL,
+                                  &add_plugin,
+                                  NULL);
 }
 
 
diff --git a/src/reclaim/reclaim_credential.c b/src/reclaim/reclaim_credential.c
index 5c8974400..42e60dc21 100644
--- a/src/reclaim/reclaim_credential.c
+++ b/src/reclaim/reclaim_credential.c
@@ -96,10 +96,10 @@ init ()
   if (GNUNET_YES == initialized)
     return;
   initialized = GNUNET_YES;
-  GNUNET_PLUGIN_load_all ("libgnunet_plugin_reclaim_credential_",
-                          NULL,
-                          &add_plugin,
-                          NULL);
+  GNUNET_PLUGIN_load_all_default ("libgnunet_plugin_reclaim_credential_",
+                                  NULL,
+                                  &add_plugin,
+                                  NULL);
 }
 
 
diff --git a/src/rest/gnunet-rest-server.c b/src/rest/gnunet-rest-server.c
index e6e03b16d..3ad60c0bc 100644
--- a/src/rest/gnunet-rest-server.c
+++ b/src/rest/gnunet-rest-server.c
@@ -1229,10 +1229,10 @@ run (void *cls,
     return;
   }
   /* Load plugins */
-  GNUNET_PLUGIN_load_all ("libgnunet_plugin_rest",
-                          (void *) cfg,
-                          &load_plugin,
-                          NULL);
+  GNUNET_PLUGIN_load_all_default ("libgnunet_plugin_rest",
+                                  (void *) cfg,
+                                  &load_plugin,
+                                  NULL);
   GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
 }
 
-- 
2.26.2

Reply via email to