]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
property: lock the lib ctx when updating the property definition cache
authorPauli <pauli@openssl.org>
Wed, 7 Apr 2021 01:32:59 +0000 (11:32 +1000)
committerPauli <pauli@openssl.org>
Thu, 8 Apr 2021 07:46:35 +0000 (17:46 +1000)
Although the store being used is adequately and properly locked, the library
context is not.  Due to the mechanisms used for fetching, it is possible for
multiple stores to live within the same library context for short periods.
This fix prevents threading issues resulting from such coincidences.

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14773)

crypto/context.c
crypto/property/defn_cache.c
include/internal/core.h

index 852f9dd7ce944c912c08825f954d7b6fee73a061..6c088e6628c5494499dd70661bdcc5b401b8e600 100644 (file)
@@ -11,6 +11,7 @@
 #include <openssl/conf.h>
 #include "internal/thread_once.h"
 #include "internal/property.h"
+#include "internal/core.h"
 
 struct ossl_lib_ctx_onfree_list_st {
     ossl_lib_ctx_onfree_fn *fn;
@@ -39,6 +40,21 @@ struct ossl_lib_ctx_st {
     struct ossl_lib_ctx_onfree_list_st *onfreelist;
 };
 
+int ossl_lib_ctx_write_lock(OSSL_LIB_CTX *ctx)
+{
+    return CRYPTO_THREAD_write_lock(ossl_lib_ctx_get_concrete(ctx)->lock);
+}
+
+int ossl_lib_ctx_read_lock(OSSL_LIB_CTX *ctx)
+{
+    return CRYPTO_THREAD_read_lock(ossl_lib_ctx_get_concrete(ctx)->lock);
+}
+
+int ossl_lib_ctx_unlock(OSSL_LIB_CTX *ctx)
+{
+    return CRYPTO_THREAD_unlock(ossl_lib_ctx_get_concrete(ctx)->lock);
+}
+
 static int context_init(OSSL_LIB_CTX *ctx)
 {
     size_t i;
index b3aefe8f8eb3c9f871cb1edddf8dce7042f72ce4..13b2d60770ae484ea789adbc1e506ca84c2fb73d 100644 (file)
@@ -13,6 +13,7 @@
 #include <openssl/lhash.h>
 #include "internal/propertyerr.h"
 #include "internal/property.h"
+#include "internal/core.h"
 #include "property_local.h"
 
 /*
@@ -74,11 +75,12 @@ OSSL_PROPERTY_LIST *ossl_prop_defn_get(OSSL_LIB_CTX *ctx, const char *prop)
     property_defns = ossl_lib_ctx_get_data(ctx,
                                            OSSL_LIB_CTX_PROPERTY_DEFN_INDEX,
                                            &property_defns_method);
-    if (property_defns == NULL)
+    if (property_defns == NULL || !ossl_lib_ctx_read_lock(ctx))
         return NULL;
 
     elem.prop = prop;
     r = lh_PROPERTY_DEFN_ELEM_retrieve(property_defns, &elem);
+    ossl_lib_ctx_unlock(ctx);
     return r != NULL ? r->defn : NULL;
 }
 
@@ -88,6 +90,7 @@ int ossl_prop_defn_set(OSSL_LIB_CTX *ctx, const char *prop,
     PROPERTY_DEFN_ELEM elem, *old, *p = NULL;
     size_t len;
     LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns;
+    int res = 1;
 
     property_defns = ossl_lib_ctx_get_data(ctx,
                                            OSSL_LIB_CTX_PROPERTY_DEFN_INDEX,
@@ -98,10 +101,12 @@ int ossl_prop_defn_set(OSSL_LIB_CTX *ctx, const char *prop,
     if (prop == NULL)
         return 1;
 
+    if (!ossl_lib_ctx_write_lock(ctx))
+        return 0;
     if (pl == NULL) {
         elem.prop = prop;
         lh_PROPERTY_DEFN_ELEM_delete(property_defns, &elem);
-        return 1;
+        goto end;
     }
     len = strlen(prop);
     p = OPENSSL_malloc(sizeof(*p) + len);
@@ -112,11 +117,14 @@ int ossl_prop_defn_set(OSSL_LIB_CTX *ctx, const char *prop,
         old = lh_PROPERTY_DEFN_ELEM_insert(property_defns, p);
         if (old != NULL) {
             property_defn_free(old);
-            return 1;
+            goto end;
         }
         if (!lh_PROPERTY_DEFN_ELEM_error(property_defns))
-            return 1;
+            goto end;
     }
     OPENSSL_free(p);
-    return 0;
+    res = 0;
+ end:
+    ossl_lib_ctx_unlock(ctx);
+    return res;
 }
index c3c2b74a63aaab30815e28bf6283bbac6c8b3e60..6e66bbeb9a2ea770dd9f9ee6d0c6f657ddf6bf6a 100644 (file)
@@ -60,4 +60,8 @@ void ossl_algorithm_do_all(OSSL_LIB_CTX *libctx, int operation_id,
                                        int no_store, void *data, int *result),
                            void *data);
 
+__owur int ossl_lib_ctx_write_lock(OSSL_LIB_CTX *ctx);
+__owur int ossl_lib_ctx_read_lock(OSSL_LIB_CTX *ctx);
+int ossl_lib_ctx_unlock(OSSL_LIB_CTX *ctx);
+
 #endif