From: Daiki Ueno Date: Mon, 22 Dec 2025 06:29:06 +0000 (+0900) Subject: pkcs11: properly fall back to thread-unsafe module init X-Git-Tag: 3.8.12~15^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f6680ada01ac8757f372cd7b97fd80e33c79c927;p=thirdparty%2Fgnutls.git pkcs11: properly fall back to thread-unsafe module init The PKCS#11 module initialization logic introduced in aa5f15a872e62e54abe58624ee393e68d1faf689 first attempts to initialize the module with CKR_NEED_TO_CREATE_THREADS|CKF_OS_LOCKING_OK, which may return either CKR_CANT_LOCK or CKR_NEED_TO_CREATE_THREADS, where the latter was previously treated as a hard error. This fixes it and also makes the second attempt to not supply any flags. Signed-off-by: Daiki Ueno --- diff --git a/.gitignore b/.gitignore index 0c24e010c9..8f00901e64 100644 --- a/.gitignore +++ b/.gitignore @@ -755,6 +755,7 @@ tests/softhsm-*.db/ tests/softhsm-distrust-after.config tests/softhsm-long-label.config tests/softhsm-neg-no-key.config +tests/softhsm-os-locking-ok.config tests/softhsm-post-handshake-with-cert-pkcs11.config tests/spki tests/spki-abstract diff --git a/lib/pkcs11.c b/lib/pkcs11.c index 021974f5fa..668d91bb13 100644 --- a/lib/pkcs11.c +++ b/lib/pkcs11.c @@ -255,10 +255,6 @@ static const struct ck_c_initialize_args default_init_args = { NULL, }; -static const struct ck_c_initialize_args no_thread_init_args = { - NULL, NULL, NULL, NULL, CKF_LIBRARY_CANT_CREATE_OS_THREADS, NULL, -}; - static void pkcs11_provider_deinit(struct gnutls_pkcs11_provider_st *provider) { p11_kit_module_finalize(provider->module); @@ -284,15 +280,22 @@ static int pkcs11_provider_init(struct gnutls_pkcs11_provider_st *provider, reserved = (char *)(p + sizeof("p11-kit:") - 1); } - /* First try with CKF_OS_LOCKING_OK, then fall back without it */ + /* First try with CKF_LIBRARY_CANT_CREATE_OS_THREADS | + * CKF_OS_LOCKING_OK, then fall back without it */ args = default_init_args; args.reserved = (void *)reserved; rv = module->C_Initialize(&args); - if (rv == CKR_CANT_LOCK) { - args = no_thread_init_args; - args.reserved = (void *)reserved; - rv = module->C_Initialize(&args); + if (rv == CKR_NEED_TO_CREATE_THREADS || rv == CKR_CANT_LOCK) { + struct ck_c_initialize_args *pargs; + if (reserved) { + memset(&args, 0, sizeof(args)); + args.reserved = (void *)reserved; + pargs = &args; + } else { + pargs = NULL; + } + rv = module->C_Initialize(pargs); } if (rv != CKR_OK) { diff --git a/tests/pkcs11/pkcs11-mock4.c b/tests/pkcs11/pkcs11-mock4.c index ffa684b52f..3fd24eae29 100644 --- a/tests/pkcs11/pkcs11-mock4.c +++ b/tests/pkcs11/pkcs11-mock4.c @@ -54,19 +54,21 @@ static CK_FUNCTION_LIST override_funcs; #define _DESTRUCTOR __attribute__((destructor)) #endif +#define LOCK_FLAGS (CKF_LIBRARY_CANT_CREATE_OS_THREADS | CKF_OS_LOCKING_OK) + static CK_RV override_C_Initialize(void *args) { CK_C_INITIALIZE_ARGS *init_args = args; static bool first = true; - assert(init_args); - if (first) { - assert(init_args->flags & CKF_OS_LOCKING_OK); + assert(init_args && + (init_args->flags & LOCK_FLAGS) == LOCK_FLAGS); first = false; return CKR_CANT_LOCK; } else { - assert(!(init_args->flags & CKF_OS_LOCKING_OK)); + assert(!init_args || + (init_args->flags & LOCK_FLAGS) != LOCK_FLAGS); } return base_C_Initialize(args);