Fix race for X509 store found by thread sanitizer
[openssl.git] / crypto / asn1 / a_dup.c
index 263c8a0c5e06a6ad5fb13184a6dbc9a70d3e7780..23d1d63808979f629541e578e4ed6241fea21655 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -28,10 +28,8 @@ void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, const void *x)
         return NULL;
 
     b = OPENSSL_malloc(i + 10);
-    if (b == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+    if (b == NULL)
         return NULL;
-    }
     p = b;
     i = i2d(x, &p);
     p2 = b;
@@ -56,6 +54,8 @@ void *ASN1_item_dup(const ASN1_ITEM *it, const void *x)
     const unsigned char *p;
     long i;
     ASN1_VALUE *ret;
+    OSSL_LIB_CTX *libctx = NULL;
+    const char *propq = NULL;
 
     if (x == NULL)
         return NULL;
@@ -67,17 +67,20 @@ void *ASN1_item_dup(const ASN1_ITEM *it, const void *x)
         asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
     }
 
-    if (asn1_cb != NULL
-        && !asn1_cb(ASN1_OP_DUP_PRE, (ASN1_VALUE **)&x, it, NULL))
-        goto auxerr;
+    if (asn1_cb != NULL) {
+        if (!asn1_cb(ASN1_OP_DUP_PRE, (ASN1_VALUE **)&x, it, NULL)
+                || !asn1_cb(ASN1_OP_GET0_LIBCTX, (ASN1_VALUE **)&x, it, &libctx)
+                || !asn1_cb(ASN1_OP_GET0_PROPQ, (ASN1_VALUE **)&x, it, &propq))
+            goto auxerr;
+    }
 
     i = ASN1_item_i2d(x, &b, it);
     if (b == NULL) {
-        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
         return NULL;
     }
     p = b;
-    ret = ASN1_item_d2i(NULL, &p, i, it);
+    ret = ASN1_item_d2i_ex(NULL, &p, i, it, libctx, propq);
     OPENSSL_free(b);
 
     if (asn1_cb != NULL