The previous commit provided some guidelines and some rules for using
locking in order to avoid deadlocks. This commit refactors the code in
order to adhere to those guidelines and rules.
Fixes#16312
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/16469)
Provide some guidelines, as well as some rules for using the locks in
provider_core.c, in order to avoid the introduction of deadlocks.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/16469)
If two threads both attempt to load the same provider at the same time,
they will first both check to see if the provider already exists. If it
doesn't then they will both then create new provider objects and call the
init function. However only one of the threads will be successful in adding
the provider to the store. For the "losing" thread we should still return
"success", but we should deinitialise and free the no longer required
provider object, and return the object that exists in the store.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15854)
An earlier stage of the refactor in the last few commits moved this
function out of provider.c because it needed access to the provider
structure internals. The final version however no longer needs this so
it is moved back again.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15854)
Create the OSSL_PROVIDER_INFO to replace struct provider_info_st.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15854)
This restriction was in place to avoid problems with recursive attempts
to aquire the flag lock/store lock from within a provider's init function.
Since those locks are no longer held when calling the init function there
is no reason for the restriction any more.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15854)
Previously providers were added to the store first, and then subsequently
initialised. This meant that during initialisation the provider object
could be shared between multiple threads and hence the locks needed to be
held. However this causes problems because the provider init function is
essentially a user callback and could do virtually anything. There are
many API calls that could be invoked that could subsequently attempt to
acquire the locks. This will fail because the locks are already held.
However, now we have refactored things so that the provider is created and
initialised before being added to the store. Therefore at the point of
initialisation the provider object is not shared with other threads and so
no locks need to be held.
Fixes#15793Fixes#15712
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15854)
This means we can distinguish providers that have been added to the
store, and those which haven't yet been.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15854)
These 2 functions have become so close to each other that they may as well
be just one function.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15854)
Update use_fallbacks to zero when we add a provider to the store rather
than when we activate it. Its only at the point that we add it to the store
that it is actually usable and visible to other threads.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15854)
Now that a provider is no longer put into the store until after it has
been activated we don't need flag_couldbechild any more. This flag was
used to indicate whether a provider was eligible for conversion into a
child provider or not. This was only really interesting for predefined
providers that were automatically created.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15854)
Rather than creating the provider, adding to the store and then activating
it, we do things the other way around, i.e. activate first and then add to
the store. This means that the activation should occur before other threads
are aware of the provider.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15854)
If provider specified in a config file are not "activated" then we defer
instantiating the provider object until it is actually needed.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15854)
Previously we created the provider object for builtin providers at the
point that OPENSSL_add_builtin() was called. Instead we delay that until
the provider is actually loaded.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15854)
Previously we instantiated all the predefined providers at the point that
we create the provider store. Instead we move them to be instantiated as we
need them.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15854)
This enables providers to register new OIDs in the same libcrypto instance
as is used by the application.
Fixes#15624
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15681)
If the DRBG is used within the scope of the FIPS OSSL_provider_init
function then it attempts to register a thread callback via c_thread_start.
However the implementation of c_thread_start assumed that the provider's
provctx was already present. However because OSSL_provider_init is still
running it was actually NULL. This means the thread callback fail to work
correctly and a memory leak resulted.
Instead of having c_thread_start use the provctx as the callback argument
we change the definition of c_thread_start to have an explicit callback
argument to use.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15278)
Where a child libctx is in use it needs to know what the current global
properties are.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15242)
This actually fixes a more subtle problem that wasn't detected which could
cause memory leaks.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/15300)
We were deferring the initial creation of the child providers until the
first fetch. This is a carry over from an earlier iteration of the child
lib ctx development and is no longer necessary. In fact we need to init
the child providers immediately otherwise not all providers quite init
correctly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15270)
If a provider explicitly loads another provider into a child libctx where
it wasn't previously loaded then we don't start treating it like a child
if the parent libctx subsequently loads the same provider.
Fixes#14925
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14991)
If the ref counts on a child provider change, then this needs to be
reflected in the parent so we add callbacks to do this.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14991)
By adding callbacks to the core this will enable (in future commits) the
ability to add/remove child providers as the providers are added/removed
from the parent libctx.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14991)
Add a child OSSL_LIB_CTX that will mirror the providers loaded into the
parent libctx. This is useful for providers that want to use algorithms
from other providers and just need to inherit the providers used by the
application.
Fixes#14925
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14991)
Where an object has multiple ex_data associated with it, then we free that
ex_data in order of priority (high priority first).
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14991)
There is no need to load providers from the config file into the default
libctx, if the current libctx that we are using isn't the default libctx.
This avoids some deadlock situations.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14991)
When the providers change, the method cache needs to be flushed. This also
impacts the cache is full partial flushes and the algorithm flushing by ID.
A new function is introduced to clear all of the operation bits in all
providers in a library context.
Fixes#15032
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15042)
A failure to obtain a lock would have resulted in much badness, now it results
in a failure return.
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14773)
If we attempt to init a provider but that init fails, then we should
still deregister any thread handlers. The provider may have failed after
these were registered.
Fixes#13338
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14576)
Using ossl_assert makes the build fail with --strict-warnings
because the ossl_assert is declared with warn_unused_result.
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14571)
We need to keep the check for prov == NULL in ossl_provider_libctx
but it is not needed in core_get_libctx as there it can happen only when
there is a serious coding error in a third party provider and returning
NULL as libctx would be seriously wrong as that has a special meaning.
The second TODO is valid but not something that is relevant
for 3.0. Change it into a normal comment.
Fixes#14377
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14535)
Some functions that lock things are void, so we just return early.
Also make ossl_namemap_empty return 0 on error. Updated the docs, and added
some code to ossl_namemap_stored() to handle the failure, and updated the
tests to allow for failure.
Fixes: #14230
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14238)
To avoid recursive lock issues, a copy is taken of the provider list and
the callbacks are made without holding the store lock.
Fixes#14251
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/14489)
Providers (particularly the FIPS provider) needs access to BIOs from libcrypto.
Libcrypto is allowed to change the internal format of the BIO structure and it
is still expected to work with providers that were already built. This means
that the libcrypto BIO must be distinct from and not castable to the provider
side OSSL_CORE_BIO.
Unfortunately, this requirement was broken in both directions. This fixes
things by forcing the two to be different and any casts break loudly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14419)
provider_init() makes changes in the provider structure, and needs a
bit of protection to ensure that doesn't happen concurrently with race
conditions.
This also demands a bit of protection of the flags, since they are
bits and presumably occupy the same byte in memory.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14354)
Without this, a provider has no way to know that an application
has finished with the array it returned earlier. A non-caching provider
requires this information.
Fixes#12974
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12974)
Add an argument to PROVIDER_try_load() that permits a provider to be
loaded without changing the fallback status. This is useful when an
additional provider needs to be loaded without perturbing any other setup.
E.g. adding mock providers as part of unit testing.
Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13652)
If the macro OSSL_FORCE_NO_CACHE_FETCH is defined, no provider will have its
fetches cached.
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14126)