diff --git a/crypto/context.c b/crypto/context.c
index 852f9dd7ce..6c088e6628 100644
--- a/crypto/context.c
+++ b/crypto/context.c
@@ -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;
diff --git a/crypto/property/defn_cache.c b/crypto/property/defn_cache.c
index b3aefe8f8e..13b2d60770 100644
--- a/crypto/property/defn_cache.c
+++ b/crypto/property/defn_cache.c
@@ -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;
 }
diff --git a/include/internal/core.h b/include/internal/core.h
index c3c2b74a63..6e66bbeb9a 100644
--- a/include/internal/core.h
+++ b/include/internal/core.h
@@ -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