From 934197611dd1260d17ae0f11ae81c1d2e85612d2 Mon Sep 17 00:00:00 2001
From: Marc Becker <marc.becker@astos.de>
Date: Fri, 22 Jul 2022 10:33:05 +0200
Subject: [PATCH] core: add provider property for loader flags

support flags for dynamic loader via provider property
set original values as defaults, use verbatim (user-supplied) value
---
 include/pkcs11-helper-1.0/pkcs11h-core.h | 11 ++++++++++-
 lib/_pkcs11h-core.h                      |  2 ++
 lib/pkcs11h-core.c                       | 13 +++++++++++--
 3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/include/pkcs11-helper-1.0/pkcs11h-core.h b/include/pkcs11-helper-1.0/pkcs11h-core.h
index 9028c277..56f87718 100644
--- a/include/pkcs11-helper-1.0/pkcs11h-core.h
+++ b/include/pkcs11-helper-1.0/pkcs11h-core.h
@@ -384,8 +384,17 @@ extern "C" {
  */
 #define PKCS11H_PROVIDER_PROPERTY_PROVIDER_DESTRUCT_HOOK_DATA 8
 
+/**
+ * @brief Provider loader flags for platform.
+ * Value type is unsigned.
+ * Default value is platform dependent:
+ *     win32 -> 0
+ *    dlopen -> RTLD_NOW | RTLD_LOCAL
+ */
+#define PKCS11H_PROVIDER_PROPERTY_LOADER_FLAGS 9
+
 /** @private */
-#define _PKCS11H_PROVIDER_PROPERTY_LAST 9
+#define _PKCS11H_PROVIDER_PROPERTY_LAST 10
 
 /** @} */
 
diff --git a/lib/_pkcs11h-core.h b/lib/_pkcs11h-core.h
index f879c0e8..1c02e35d 100644
--- a/lib/_pkcs11h-core.h
+++ b/lib/_pkcs11h-core.h
@@ -134,6 +134,8 @@ struct _pkcs11h_provider_s {
 #if defined(ENABLE_PKCS11H_SLOTEVENT)
 	_pkcs11h_thread_t slotevent_thread;
 #endif
+
+	unsigned loader_flags;
 };
 
 struct _pkcs11h_session_s {
diff --git a/lib/pkcs11h-core.c b/lib/pkcs11h-core.c
index 0bf11e87..409ad9e2 100644
--- a/lib/pkcs11h-core.c
+++ b/lib/pkcs11h-core.c
@@ -138,6 +138,7 @@ static const char * __pkcs11h_provider_preperty_names[] = {
 	"init_args",
 	"provider_destruct_hook",
 	"provider_destruct_hook_data",
+	"provider_loader_flags",
 	NULL
 };
 
@@ -916,6 +917,10 @@ pkcs11h_registerProvider (
 		reference
 	);
 
+#if !defined(_WIN32)
+	provider->loader_flags = RTLD_NOW | RTLD_LOCAL;
+#endif
+
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
 		"PKCS#11: pkcs11h_registerProvider Provider '%s'",
@@ -1001,6 +1006,7 @@ pkcs11h_setProviderPropertyByName (
 		case PKCS11H_PROVIDER_PROPERTY_SLOT_EVENT_METHOD:
 		case PKCS11H_PROVIDER_PROPERTY_MASK_PRIVATE_MODE:
 		case PKCS11H_PROVIDER_PROPERTY_SLOT_POLL_INTERVAL:
+		case PKCS11H_PROVIDER_PROPERTY_LOADER_FLAGS:
 			*(unsigned *)value = (unsigned)strtol(value_str, 0, 0);
 			value_size = sizeof(unsigned);
 		break;
@@ -1084,6 +1090,9 @@ __pkcs11h_providerPropertyAddress(
 		case PKCS11H_PROVIDER_PROPERTY_PROVIDER_DESTRUCT_HOOK_DATA:
 			*value = &provider->destruct_hook_data;
 			*value_size = sizeof(provider->destruct_hook_data);
+		case PKCS11H_PROVIDER_PROPERTY_LOADER_FLAGS:
+			*value = &provider->loader_flags;
+			*value_size = sizeof(provider->loader_flags);
 		break;
 	}
 	rv = CKR_OK;
@@ -1254,9 +1263,9 @@ pkcs11h_initializeProvider (
 	}
 
 #if defined(_WIN32)
-	provider->handle = LoadLibraryA (provider->provider_location);
+	provider->handle = LoadLibraryExA (provider->provider_location, NULL, provider->loader_flags);
 #else
-	provider->handle = dlopen (provider->provider_location, RTLD_NOW | RTLD_LOCAL);
+	provider->handle = dlopen (provider->provider_location, provider->loader_flags);
 #endif
 
 	if (provider->handle == NULL) {
