{
QUERY *p = NULL;
int res = 1;
+ int skip_providerless = 0;
if (method == NULL) {
p = ossl_method_store_atomic_find_in_list(sa, nid, prov, prop_query);
if (p != NULL) {
ossl_method_store_atomic_archive(sa, p);
p = ossl_method_store_atomic_find_in_list(sa, nid, NULL, prop_query);
+ /*
+ * Note: We want to preserve previous behavior here. Namely, if we load multiple
+ * providers we don't want to change the algorithm implementation we return if we've
+ * already potentially returned one from another provider. So if an alg exists for
+ * a given nid/prop query with a NULL provider, don't replace the one we have.
+ * Instead, let the oldest one win
+ */
if (p != NULL)
- ossl_method_store_atomic_archive(sa, p);
+ skip_providerless = 1;
}
p = QUERY_new(strlen(prop_query));
if (p != NULL) {
goto err;
}
- /*
- * We also want to add this method into the cache against a key computed _only_
- * from nid and property query. This lets us match in the event someone does a lookup
- * against a NULL provider (i.e. the "any provided alg will do" match
- */
- p = QUERY_new(strlen(prop_query));
- if (p == NULL)
- goto err;
- TSAN_BENIGN(p, "Unpublished value is safe on subsequent read");
- p->saptr = sa;
- p->nid = nid;
- p->prov = NULL;
- p->archived = 0;
- strcpy(p->prop_query, prop_query);
- p->method.method = method;
- p->method.up_ref = method_up_ref;
- p->method.free = method_destruct;
- if (!ossl_method_up_ref(&p->method))
- goto err;
- if (!ossl_method_store_atomic_insert_to_list(sa, p)) {
- ossl_method_free(&p->method);
- goto err;
+ if (skip_providerless == 0) {
+ /*
+ * We also want to add this method into the cache against a key computed _only_
+ * from nid and property query. This lets us match in the event someone does a lookup
+ * against a NULL provider (i.e. the "any provided alg will do" match
+ */
+ p = QUERY_new(strlen(prop_query));
+ if (p == NULL)
+ goto err;
+ TSAN_BENIGN(p, "Unpublished value is safe on subsequent read");
+ p->saptr = sa;
+ p->nid = nid;
+ p->prov = NULL;
+ p->archived = 0;
+ strcpy(p->prop_query, prop_query);
+ p->method.method = method;
+ p->method.up_ref = method_up_ref;
+ p->method.free = method_destruct;
+ if (!ossl_method_up_ref(&p->method))
+ goto err;
+ if (!ossl_method_store_atomic_insert_to_list(sa, p)) {
+ ossl_method_free(&p->method);
+ goto err;
+ }
}
-
goto end;
}
err:
|| result != v + i)
errors++;
}
- /* There is a tiny probability that this will fail when it shouldn't */
- res = !TEST_int_gt(errors, 0);
+
+ res = TEST_int_eq(errors, 0);
err:
ossl_method_store_free(store);
*/
ossl_method_store_cache_set(store, &prov, 1, "", &refs, counted_up_ref,
counted_down_ref);
- if (!TEST_int_eq(refs, 5)
+ if (!TEST_int_eq(refs, 4)
|| !TEST_true(ossl_method_store_cache_get(store, &prov, 1, "",
&result))
|| !TEST_ptr_eq(result, &refs))