threadstest.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116
  1. /*
  2. * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. /*
  10. * The test_multi_downgrade_shared_pkey function tests the thread safety of a
  11. * deprecated function.
  12. */
  13. #ifndef OPENSSL_NO_DEPRECATED_3_0
  14. # define OPENSSL_SUPPRESS_DEPRECATED
  15. #endif
  16. #if defined(_WIN32)
  17. # include <windows.h>
  18. #endif
  19. #include <string.h>
  20. #include <internal/cryptlib.h>
  21. #include <internal/thread_arch.h>
  22. #include <internal/thread.h>
  23. #include <openssl/crypto.h>
  24. #include <openssl/rsa.h>
  25. #include <openssl/aes.h>
  26. #include <openssl/err.h>
  27. #include <openssl/rand.h>
  28. #include <openssl/thread.h>
  29. #include "internal/tsan_assist.h"
  30. #include "internal/nelem.h"
  31. #include "testutil.h"
  32. #include "threadstest.h"
  33. /* Limit the maximum number of threads */
  34. #define MAXIMUM_THREADS 10
  35. /* Limit the maximum number of providers loaded into a library context */
  36. #define MAXIMUM_PROVIDERS 4
  37. static int do_fips = 0;
  38. static char *privkey;
  39. static char *config_file = NULL;
  40. static int multidefault_run = 0;
  41. static const char *default_provider[] = { "default", NULL };
  42. static const char *fips_provider[] = { "fips", NULL };
  43. static const char *fips_and_default_providers[] = { "default", "fips", NULL };
  44. static CRYPTO_RWLOCK *global_lock;
  45. #ifdef TSAN_REQUIRES_LOCKING
  46. static CRYPTO_RWLOCK *tsan_lock;
  47. #endif
  48. /* Grab a globally unique integer value, return 0 on failure */
  49. static int get_new_uid(void)
  50. {
  51. /*
  52. * Start with a nice large number to avoid potential conflicts when
  53. * we generate a new OID.
  54. */
  55. static TSAN_QUALIFIER int current_uid = 1 << (sizeof(int) * 8 - 2);
  56. #ifdef TSAN_REQUIRES_LOCKING
  57. int r;
  58. if (!TEST_true(CRYPTO_THREAD_write_lock(tsan_lock)))
  59. return 0;
  60. r = ++current_uid;
  61. if (!TEST_true(CRYPTO_THREAD_unlock(tsan_lock)))
  62. return 0;
  63. return r;
  64. #else
  65. return tsan_counter(&current_uid);
  66. #endif
  67. }
  68. static int test_lock(void)
  69. {
  70. CRYPTO_RWLOCK *lock = CRYPTO_THREAD_lock_new();
  71. int res;
  72. res = TEST_true(CRYPTO_THREAD_read_lock(lock))
  73. && TEST_true(CRYPTO_THREAD_unlock(lock))
  74. && TEST_true(CRYPTO_THREAD_write_lock(lock))
  75. && TEST_true(CRYPTO_THREAD_unlock(lock));
  76. CRYPTO_THREAD_lock_free(lock);
  77. return res;
  78. }
  79. static CRYPTO_ONCE once_run = CRYPTO_ONCE_STATIC_INIT;
  80. static unsigned once_run_count = 0;
  81. static void once_do_run(void)
  82. {
  83. once_run_count++;
  84. }
  85. static void once_run_thread_cb(void)
  86. {
  87. CRYPTO_THREAD_run_once(&once_run, once_do_run);
  88. }
  89. static int test_once(void)
  90. {
  91. thread_t thread;
  92. if (!TEST_true(run_thread(&thread, once_run_thread_cb))
  93. || !TEST_true(wait_for_thread(thread))
  94. || !CRYPTO_THREAD_run_once(&once_run, once_do_run)
  95. || !TEST_int_eq(once_run_count, 1))
  96. return 0;
  97. return 1;
  98. }
  99. static CRYPTO_THREAD_LOCAL thread_local_key;
  100. static unsigned destructor_run_count = 0;
  101. static int thread_local_thread_cb_ok = 0;
  102. static void thread_local_destructor(void *arg)
  103. {
  104. unsigned *count;
  105. if (arg == NULL)
  106. return;
  107. count = arg;
  108. (*count)++;
  109. }
  110. static void thread_local_thread_cb(void)
  111. {
  112. void *ptr;
  113. ptr = CRYPTO_THREAD_get_local(&thread_local_key);
  114. if (!TEST_ptr_null(ptr)
  115. || !TEST_true(CRYPTO_THREAD_set_local(&thread_local_key,
  116. &destructor_run_count)))
  117. return;
  118. ptr = CRYPTO_THREAD_get_local(&thread_local_key);
  119. if (!TEST_ptr_eq(ptr, &destructor_run_count))
  120. return;
  121. thread_local_thread_cb_ok = 1;
  122. }
  123. static int test_thread_local(void)
  124. {
  125. thread_t thread;
  126. void *ptr = NULL;
  127. if (!TEST_true(CRYPTO_THREAD_init_local(&thread_local_key,
  128. thread_local_destructor)))
  129. return 0;
  130. ptr = CRYPTO_THREAD_get_local(&thread_local_key);
  131. if (!TEST_ptr_null(ptr)
  132. || !TEST_true(run_thread(&thread, thread_local_thread_cb))
  133. || !TEST_true(wait_for_thread(thread))
  134. || !TEST_int_eq(thread_local_thread_cb_ok, 1))
  135. return 0;
  136. #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
  137. ptr = CRYPTO_THREAD_get_local(&thread_local_key);
  138. if (!TEST_ptr_null(ptr))
  139. return 0;
  140. # if !defined(OPENSSL_SYS_WINDOWS)
  141. if (!TEST_int_eq(destructor_run_count, 1))
  142. return 0;
  143. # endif
  144. #endif
  145. if (!TEST_true(CRYPTO_THREAD_cleanup_local(&thread_local_key)))
  146. return 0;
  147. return 1;
  148. }
  149. static int test_atomic(void)
  150. {
  151. int val = 0, ret = 0, testresult = 0;
  152. uint64_t val64 = 1, ret64 = 0;
  153. CRYPTO_RWLOCK *lock = CRYPTO_THREAD_lock_new();
  154. if (!TEST_ptr(lock))
  155. return 0;
  156. if (CRYPTO_atomic_add(&val, 1, &ret, NULL)) {
  157. /* This succeeds therefore we're on a platform with lockless atomics */
  158. if (!TEST_int_eq(val, 1) || !TEST_int_eq(val, ret))
  159. goto err;
  160. } else {
  161. /* This failed therefore we're on a platform without lockless atomics */
  162. if (!TEST_int_eq(val, 0) || !TEST_int_eq(val, ret))
  163. goto err;
  164. }
  165. val = 0;
  166. ret = 0;
  167. if (!TEST_true(CRYPTO_atomic_add(&val, 1, &ret, lock)))
  168. goto err;
  169. if (!TEST_int_eq(val, 1) || !TEST_int_eq(val, ret))
  170. goto err;
  171. if (CRYPTO_atomic_or(&val64, 2, &ret64, NULL)) {
  172. /* This succeeds therefore we're on a platform with lockless atomics */
  173. if (!TEST_uint_eq((unsigned int)val64, 3)
  174. || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
  175. goto err;
  176. } else {
  177. /* This failed therefore we're on a platform without lockless atomics */
  178. if (!TEST_uint_eq((unsigned int)val64, 1)
  179. || !TEST_int_eq((unsigned int)ret64, 0))
  180. goto err;
  181. }
  182. val64 = 1;
  183. ret64 = 0;
  184. if (!TEST_true(CRYPTO_atomic_or(&val64, 2, &ret64, lock)))
  185. goto err;
  186. if (!TEST_uint_eq((unsigned int)val64, 3)
  187. || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
  188. goto err;
  189. ret64 = 0;
  190. if (CRYPTO_atomic_load(&val64, &ret64, NULL)) {
  191. /* This succeeds therefore we're on a platform with lockless atomics */
  192. if (!TEST_uint_eq((unsigned int)val64, 3)
  193. || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
  194. goto err;
  195. } else {
  196. /* This failed therefore we're on a platform without lockless atomics */
  197. if (!TEST_uint_eq((unsigned int)val64, 3)
  198. || !TEST_int_eq((unsigned int)ret64, 0))
  199. goto err;
  200. }
  201. ret64 = 0;
  202. if (!TEST_true(CRYPTO_atomic_load(&val64, &ret64, lock)))
  203. goto err;
  204. if (!TEST_uint_eq((unsigned int)val64, 3)
  205. || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
  206. goto err;
  207. testresult = 1;
  208. err:
  209. CRYPTO_THREAD_lock_free(lock);
  210. return testresult;
  211. }
  212. static OSSL_LIB_CTX *multi_libctx = NULL;
  213. static int multi_success;
  214. static OSSL_PROVIDER *multi_provider[MAXIMUM_PROVIDERS + 1];
  215. static size_t multi_num_threads;
  216. static thread_t multi_threads[MAXIMUM_THREADS];
  217. static void multi_intialise(void)
  218. {
  219. multi_success = 1;
  220. multi_libctx = NULL;
  221. multi_num_threads = 0;
  222. memset(multi_threads, 0, sizeof(multi_threads));
  223. memset(multi_provider, 0, sizeof(multi_provider));
  224. }
  225. static void multi_set_success(int ok)
  226. {
  227. if (CRYPTO_THREAD_write_lock(global_lock) == 0) {
  228. /* not synchronized, but better than not reporting failure */
  229. multi_success = ok;
  230. return;
  231. }
  232. multi_success = ok;
  233. CRYPTO_THREAD_unlock(global_lock);
  234. }
  235. static void thead_teardown_libctx(void)
  236. {
  237. OSSL_PROVIDER **p;
  238. for (p = multi_provider; *p != NULL; p++)
  239. OSSL_PROVIDER_unload(*p);
  240. OSSL_LIB_CTX_free(multi_libctx);
  241. multi_intialise();
  242. }
  243. static int thread_setup_libctx(int libctx, const char *providers[])
  244. {
  245. size_t n;
  246. if (libctx && !TEST_true(test_get_libctx(&multi_libctx, NULL, config_file,
  247. NULL, NULL)))
  248. return 0;
  249. if (providers != NULL)
  250. for (n = 0; providers[n] != NULL; n++)
  251. if (!TEST_size_t_lt(n, MAXIMUM_PROVIDERS)
  252. || !TEST_ptr(multi_provider[n] = OSSL_PROVIDER_load(multi_libctx,
  253. providers[n]))) {
  254. thead_teardown_libctx();
  255. return 0;
  256. }
  257. return 1;
  258. }
  259. static int teardown_threads(void)
  260. {
  261. size_t i;
  262. for (i = 0; i < multi_num_threads; i++)
  263. if (!TEST_true(wait_for_thread(multi_threads[i])))
  264. return 0;
  265. return 1;
  266. }
  267. static int start_threads(size_t n, void (*thread_func)(void))
  268. {
  269. size_t i;
  270. if (!TEST_size_t_le(multi_num_threads + n, MAXIMUM_THREADS))
  271. return 0;
  272. for (i = 0 ; i < n; i++)
  273. if (!TEST_true(run_thread(multi_threads + multi_num_threads++, thread_func)))
  274. return 0;
  275. return 1;
  276. }
  277. /* Template multi-threaded test function */
  278. static int thread_run_test(void (*main_func)(void),
  279. size_t num_threads, void (*thread_func)(void),
  280. int libctx, const char *providers[])
  281. {
  282. int testresult = 0;
  283. multi_intialise();
  284. if (!thread_setup_libctx(libctx, providers)
  285. || !start_threads(num_threads, thread_func))
  286. goto err;
  287. if (main_func != NULL)
  288. main_func();
  289. if (!teardown_threads()
  290. || !TEST_true(multi_success))
  291. goto err;
  292. testresult = 1;
  293. err:
  294. thead_teardown_libctx();
  295. return testresult;
  296. }
  297. static void thread_general_worker(void)
  298. {
  299. EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
  300. EVP_MD *md = EVP_MD_fetch(multi_libctx, "SHA2-256", NULL);
  301. EVP_CIPHER_CTX *cipherctx = EVP_CIPHER_CTX_new();
  302. EVP_CIPHER *ciph = EVP_CIPHER_fetch(multi_libctx, "AES-128-CBC", NULL);
  303. const char *message = "Hello World";
  304. size_t messlen = strlen(message);
  305. /* Should be big enough for encryption output too */
  306. unsigned char out[EVP_MAX_MD_SIZE];
  307. const unsigned char key[AES_BLOCK_SIZE] = {
  308. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
  309. 0x0c, 0x0d, 0x0e, 0x0f
  310. };
  311. const unsigned char iv[AES_BLOCK_SIZE] = {
  312. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
  313. 0x0c, 0x0d, 0x0e, 0x0f
  314. };
  315. unsigned int mdoutl;
  316. int ciphoutl;
  317. EVP_PKEY *pkey = NULL;
  318. int testresult = 0;
  319. int i, isfips;
  320. isfips = OSSL_PROVIDER_available(multi_libctx, "fips");
  321. if (!TEST_ptr(mdctx)
  322. || !TEST_ptr(md)
  323. || !TEST_ptr(cipherctx)
  324. || !TEST_ptr(ciph))
  325. goto err;
  326. /* Do some work */
  327. for (i = 0; i < 5; i++) {
  328. if (!TEST_true(EVP_DigestInit_ex(mdctx, md, NULL))
  329. || !TEST_true(EVP_DigestUpdate(mdctx, message, messlen))
  330. || !TEST_true(EVP_DigestFinal(mdctx, out, &mdoutl)))
  331. goto err;
  332. }
  333. for (i = 0; i < 5; i++) {
  334. if (!TEST_true(EVP_EncryptInit_ex(cipherctx, ciph, NULL, key, iv))
  335. || !TEST_true(EVP_EncryptUpdate(cipherctx, out, &ciphoutl,
  336. (unsigned char *)message,
  337. messlen))
  338. || !TEST_true(EVP_EncryptFinal(cipherctx, out, &ciphoutl)))
  339. goto err;
  340. }
  341. /*
  342. * We want the test to run quickly - not securely.
  343. * Therefore we use an insecure bit length where we can (512).
  344. * In the FIPS module though we must use a longer length.
  345. */
  346. pkey = EVP_PKEY_Q_keygen(multi_libctx, NULL, "RSA", isfips ? 2048 : 512);
  347. if (!TEST_ptr(pkey))
  348. goto err;
  349. testresult = 1;
  350. err:
  351. EVP_MD_CTX_free(mdctx);
  352. EVP_MD_free(md);
  353. EVP_CIPHER_CTX_free(cipherctx);
  354. EVP_CIPHER_free(ciph);
  355. EVP_PKEY_free(pkey);
  356. if (!testresult)
  357. multi_set_success(0);
  358. }
  359. static void thread_multi_simple_fetch(void)
  360. {
  361. EVP_MD *md = EVP_MD_fetch(multi_libctx, "SHA2-256", NULL);
  362. if (md != NULL)
  363. EVP_MD_free(md);
  364. else
  365. multi_set_success(0);
  366. }
  367. static EVP_PKEY *shared_evp_pkey = NULL;
  368. static void thread_shared_evp_pkey(void)
  369. {
  370. char *msg = "Hello World";
  371. unsigned char ctbuf[256];
  372. unsigned char ptbuf[256];
  373. size_t ptlen, ctlen = sizeof(ctbuf);
  374. EVP_PKEY_CTX *ctx = NULL;
  375. int success = 0;
  376. int i;
  377. for (i = 0; i < 1 + do_fips; i++) {
  378. if (i > 0)
  379. EVP_PKEY_CTX_free(ctx);
  380. ctx = EVP_PKEY_CTX_new_from_pkey(multi_libctx, shared_evp_pkey,
  381. i == 0 ? "provider=default"
  382. : "provider=fips");
  383. if (!TEST_ptr(ctx))
  384. goto err;
  385. if (!TEST_int_ge(EVP_PKEY_encrypt_init(ctx), 0)
  386. || !TEST_int_ge(EVP_PKEY_encrypt(ctx, ctbuf, &ctlen,
  387. (unsigned char *)msg, strlen(msg)),
  388. 0))
  389. goto err;
  390. EVP_PKEY_CTX_free(ctx);
  391. ctx = EVP_PKEY_CTX_new_from_pkey(multi_libctx, shared_evp_pkey, NULL);
  392. if (!TEST_ptr(ctx))
  393. goto err;
  394. ptlen = sizeof(ptbuf);
  395. if (!TEST_int_ge(EVP_PKEY_decrypt_init(ctx), 0)
  396. || !TEST_int_gt(EVP_PKEY_decrypt(ctx, ptbuf, &ptlen, ctbuf, ctlen),
  397. 0)
  398. || !TEST_mem_eq(msg, strlen(msg), ptbuf, ptlen))
  399. goto err;
  400. }
  401. success = 1;
  402. err:
  403. EVP_PKEY_CTX_free(ctx);
  404. if (!success)
  405. multi_set_success(0);
  406. }
  407. static void thread_provider_load_unload(void)
  408. {
  409. OSSL_PROVIDER *deflt = OSSL_PROVIDER_load(multi_libctx, "default");
  410. if (!TEST_ptr(deflt)
  411. || !TEST_true(OSSL_PROVIDER_available(multi_libctx, "default")))
  412. multi_set_success(0);
  413. OSSL_PROVIDER_unload(deflt);
  414. }
  415. static int test_multi_general_worker_default_provider(void)
  416. {
  417. return thread_run_test(&thread_general_worker, 2, &thread_general_worker,
  418. 1, default_provider);
  419. }
  420. static int test_multi_general_worker_fips_provider(void)
  421. {
  422. if (!do_fips)
  423. return TEST_skip("FIPS not supported");
  424. return thread_run_test(&thread_general_worker, 2, &thread_general_worker,
  425. 1, fips_provider);
  426. }
  427. static int test_multi_fetch_worker(void)
  428. {
  429. return thread_run_test(&thread_multi_simple_fetch,
  430. 2, &thread_multi_simple_fetch, 1, default_provider);
  431. }
  432. static int test_multi_shared_pkey_common(void (*worker)(void))
  433. {
  434. int testresult = 0;
  435. multi_intialise();
  436. if (!thread_setup_libctx(1, do_fips ? fips_and_default_providers
  437. : default_provider)
  438. || !TEST_ptr(shared_evp_pkey = load_pkey_pem(privkey, multi_libctx))
  439. || !start_threads(1, &thread_shared_evp_pkey)
  440. || !start_threads(1, worker))
  441. goto err;
  442. thread_shared_evp_pkey();
  443. if (!teardown_threads()
  444. || !TEST_true(multi_success))
  445. goto err;
  446. testresult = 1;
  447. err:
  448. EVP_PKEY_free(shared_evp_pkey);
  449. thead_teardown_libctx();
  450. return testresult;
  451. }
  452. #ifndef OPENSSL_NO_DEPRECATED_3_0
  453. static void thread_downgrade_shared_evp_pkey(void)
  454. {
  455. /*
  456. * This test is only relevant for deprecated functions that perform
  457. * downgrading
  458. */
  459. if (EVP_PKEY_get0_RSA(shared_evp_pkey) == NULL)
  460. multi_set_success(0);
  461. }
  462. static int test_multi_downgrade_shared_pkey(void)
  463. {
  464. return test_multi_shared_pkey_common(&thread_downgrade_shared_evp_pkey);
  465. }
  466. #endif
  467. static int test_multi_shared_pkey(void)
  468. {
  469. return test_multi_shared_pkey_common(&thread_shared_evp_pkey);
  470. }
  471. static int test_multi_load_unload_provider(void)
  472. {
  473. EVP_MD *sha256 = NULL;
  474. OSSL_PROVIDER *prov = NULL;
  475. int testresult = 0;
  476. multi_intialise();
  477. if (!thread_setup_libctx(1, NULL)
  478. || !TEST_ptr(prov = OSSL_PROVIDER_load(multi_libctx, "default"))
  479. || !TEST_ptr(sha256 = EVP_MD_fetch(multi_libctx, "SHA2-256", NULL))
  480. || !TEST_true(OSSL_PROVIDER_unload(prov)))
  481. goto err;
  482. prov = NULL;
  483. if (!start_threads(2, &thread_provider_load_unload))
  484. goto err;
  485. thread_provider_load_unload();
  486. if (!teardown_threads()
  487. || !TEST_true(multi_success))
  488. goto err;
  489. testresult = 1;
  490. err:
  491. OSSL_PROVIDER_unload(prov);
  492. EVP_MD_free(sha256);
  493. thead_teardown_libctx();
  494. return testresult;
  495. }
  496. static char *multi_load_provider = "legacy";
  497. /*
  498. * This test attempts to load several providers at the same time, and if
  499. * run with a thread sanitizer, should crash if the core provider code
  500. * doesn't synchronize well enough.
  501. */
  502. static void test_multi_load_worker(void)
  503. {
  504. OSSL_PROVIDER *prov;
  505. if (!TEST_ptr(prov = OSSL_PROVIDER_load(multi_libctx, multi_load_provider))
  506. || !TEST_true(OSSL_PROVIDER_unload(prov)))
  507. multi_set_success(0);
  508. }
  509. static int test_multi_default(void)
  510. {
  511. /* Avoid running this test twice */
  512. if (multidefault_run) {
  513. TEST_skip("multi default test already run");
  514. return 1;
  515. }
  516. multidefault_run = 1;
  517. return thread_run_test(&thread_multi_simple_fetch,
  518. 2, &thread_multi_simple_fetch, 0, default_provider);
  519. }
  520. static int test_multi_load(void)
  521. {
  522. int res = 1;
  523. OSSL_PROVIDER *prov;
  524. /* The multidefault test must run prior to this test */
  525. if (!multidefault_run) {
  526. TEST_info("Running multi default test first");
  527. res = test_multi_default();
  528. }
  529. /*
  530. * We use the legacy provider in test_multi_load_worker because it uses a
  531. * child libctx that might hit more codepaths that might be sensitive to
  532. * threading issues. But in a no-legacy build that won't be loadable so
  533. * we use the default provider instead.
  534. */
  535. prov = OSSL_PROVIDER_load(NULL, "legacy");
  536. if (prov == NULL) {
  537. TEST_info("Cannot load legacy provider - assuming this is a no-legacy build");
  538. multi_load_provider = "default";
  539. }
  540. OSSL_PROVIDER_unload(prov);
  541. return thread_run_test(NULL, MAXIMUM_THREADS, &test_multi_load_worker, 0,
  542. NULL) && res;
  543. }
  544. static void test_obj_create_one(void)
  545. {
  546. char tids[12], oid[40], sn[30], ln[30];
  547. int id = get_new_uid();
  548. BIO_snprintf(tids, sizeof(tids), "%d", id);
  549. BIO_snprintf(oid, sizeof(oid), "1.3.6.1.4.1.16604.%s", tids);
  550. BIO_snprintf(sn, sizeof(sn), "short-name-%s", tids);
  551. BIO_snprintf(ln, sizeof(ln), "long-name-%s", tids);
  552. if (!TEST_int_ne(id, 0)
  553. || !TEST_true(id = OBJ_create(oid, sn, ln))
  554. || !TEST_true(OBJ_add_sigid(id, NID_sha3_256, NID_rsa)))
  555. multi_set_success(0);
  556. }
  557. static int test_obj_add(void)
  558. {
  559. return thread_run_test(&test_obj_create_one,
  560. MAXIMUM_THREADS, &test_obj_create_one,
  561. 1, default_provider);
  562. }
  563. static void test_lib_ctx_load_config_worker(void)
  564. {
  565. if (!TEST_int_eq(OSSL_LIB_CTX_load_config(multi_libctx, config_file), 1))
  566. multi_set_success(0);
  567. }
  568. static int test_lib_ctx_load_config(void)
  569. {
  570. return thread_run_test(&test_lib_ctx_load_config_worker,
  571. MAXIMUM_THREADS, &test_lib_ctx_load_config_worker,
  572. 1, default_provider);
  573. }
  574. #if !defined(OPENSSL_NO_DGRAM) && !defined(OPENSSL_NO_SOCK)
  575. static BIO *multi_bio1, *multi_bio2;
  576. static void test_bio_dgram_pair_worker(void)
  577. {
  578. ossl_unused int r;
  579. int ok = 0;
  580. uint8_t ch = 0;
  581. uint8_t scratch[64];
  582. BIO_MSG msg = {0};
  583. size_t num_processed = 0;
  584. if (!TEST_int_eq(RAND_bytes_ex(multi_libctx, &ch, 1, 64), 1))
  585. goto err;
  586. msg.data = scratch;
  587. msg.data_len = sizeof(scratch);
  588. /*
  589. * We do not test for failure here as recvmmsg may fail if no sendmmsg
  590. * has been called yet. The purpose of this code is to exercise tsan.
  591. */
  592. if (ch & 2)
  593. r = BIO_sendmmsg(ch & 1 ? multi_bio2 : multi_bio1, &msg,
  594. sizeof(BIO_MSG), 1, 0, &num_processed);
  595. else
  596. r = BIO_recvmmsg(ch & 1 ? multi_bio2 : multi_bio1, &msg,
  597. sizeof(BIO_MSG), 1, 0, &num_processed);
  598. ok = 1;
  599. err:
  600. if (ok == 0)
  601. multi_set_success(0);
  602. }
  603. static int test_bio_dgram_pair(void)
  604. {
  605. int r;
  606. BIO *bio1 = NULL, *bio2 = NULL;
  607. r = BIO_new_bio_dgram_pair(&bio1, 0, &bio2, 0);
  608. if (!TEST_int_eq(r, 1))
  609. goto err;
  610. multi_bio1 = bio1;
  611. multi_bio2 = bio2;
  612. r = thread_run_test(&test_bio_dgram_pair_worker,
  613. MAXIMUM_THREADS, &test_bio_dgram_pair_worker,
  614. 1, default_provider);
  615. err:
  616. BIO_free(bio1);
  617. BIO_free(bio2);
  618. return r;
  619. }
  620. #endif
  621. static int test_thread_reported_flags(void)
  622. {
  623. uint32_t flags = OSSL_get_thread_support_flags();
  624. #if !defined(OPENSSL_THREADS)
  625. if (!TEST_int_eq(flags, 0))
  626. return 0;
  627. #endif
  628. #if defined(OPENSSL_NO_THREAD_POOL)
  629. if (!TEST_int_eq(flags & OSSL_THREAD_SUPPORT_FLAG_THREAD_POOL, 0))
  630. return 0;
  631. #else
  632. if (!TEST_int_eq(flags & OSSL_THREAD_SUPPORT_FLAG_THREAD_POOL,
  633. OSSL_THREAD_SUPPORT_FLAG_THREAD_POOL))
  634. return 0;
  635. #endif
  636. #if defined(OPENSSL_NO_DEFAULT_THREAD_POOL)
  637. if (!TEST_int_eq(flags & OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN, 0))
  638. return 0;
  639. #else
  640. if (!TEST_int_eq(flags & OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN,
  641. OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN))
  642. return 0;
  643. #endif
  644. return 1;
  645. }
  646. #if defined(OPENSSL_THREADS)
  647. # define TEST_THREAD_NATIVE_FN_SET_VALUE 1
  648. static uint32_t test_thread_native_fn(void *data)
  649. {
  650. uint32_t *ldata = (uint32_t*) data;
  651. *ldata = *ldata + 1;
  652. return *ldata - 1;
  653. }
  654. /* Tests of native threads */
  655. static int test_thread_native(void)
  656. {
  657. uint32_t retval;
  658. uint32_t local;
  659. CRYPTO_THREAD *t;
  660. /* thread spawn, join */
  661. local = 1;
  662. t = ossl_crypto_thread_native_start(test_thread_native_fn, &local, 1);
  663. if (!TEST_ptr(t))
  664. return 0;
  665. /*
  666. * pthread_join results in undefined behaviour if called on a joined
  667. * thread. We do not impose such restrictions, so it's up to us to
  668. * ensure that this does not happen (thread sanitizer will warn us
  669. * if we do).
  670. */
  671. if (!TEST_int_eq(ossl_crypto_thread_native_join(t, &retval), 1))
  672. return 0;
  673. if (!TEST_int_eq(ossl_crypto_thread_native_join(t, &retval), 1))
  674. return 0;
  675. if (!TEST_int_eq(retval, 1) || !TEST_int_eq(local, 2))
  676. return 0;
  677. if (!TEST_int_eq(ossl_crypto_thread_native_clean(t), 1))
  678. return 0;
  679. t = NULL;
  680. if (!TEST_int_eq(ossl_crypto_thread_native_clean(t), 0))
  681. return 0;
  682. return 1;
  683. }
  684. #if !defined(OPENSSL_NO_DEFAULT_THREAD_POOL)
  685. static int test_thread_internal(void)
  686. {
  687. uint32_t retval[3];
  688. uint32_t local[3] = { 0 };
  689. uint32_t threads_supported;
  690. size_t i;
  691. void *t[3];
  692. OSSL_LIB_CTX *cust_ctx = OSSL_LIB_CTX_new();
  693. threads_supported = OSSL_get_thread_support_flags();
  694. threads_supported &= OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN;
  695. if (threads_supported == 0) {
  696. if (!TEST_uint64_t_eq(OSSL_get_max_threads(NULL), 0))
  697. return 0;
  698. if (!TEST_uint64_t_eq(OSSL_get_max_threads(cust_ctx), 0))
  699. return 0;
  700. if (!TEST_int_eq(OSSL_set_max_threads(NULL, 1), 0))
  701. return 0;
  702. if (!TEST_int_eq(OSSL_set_max_threads(cust_ctx, 1), 0))
  703. return 0;
  704. if (!TEST_uint64_t_eq(OSSL_get_max_threads(NULL), 0))
  705. return 0;
  706. if (!TEST_uint64_t_eq(OSSL_get_max_threads(cust_ctx), 0))
  707. return 0;
  708. t[0] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[0]);
  709. if (!TEST_ptr_null(t[0]))
  710. return 0;
  711. return 1;
  712. }
  713. /* fail when not allowed to use threads */
  714. if (!TEST_uint64_t_eq(OSSL_get_max_threads(NULL), 0))
  715. return 0;
  716. t[0] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[0]);
  717. if (!TEST_ptr_null(t[0]))
  718. return 0;
  719. /* fail when enabled on a different context */
  720. if (!TEST_uint64_t_eq(OSSL_get_max_threads(cust_ctx), 0))
  721. return 0;
  722. if (!TEST_int_eq(OSSL_set_max_threads(cust_ctx, 1), 1))
  723. return 0;
  724. if (!TEST_uint64_t_eq(OSSL_get_max_threads(NULL), 0))
  725. return 0;
  726. if (!TEST_uint64_t_eq(OSSL_get_max_threads(cust_ctx), 1))
  727. return 0;
  728. t[0] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[0]);
  729. if (!TEST_ptr_null(t[0]))
  730. return 0;
  731. if (!TEST_int_eq(OSSL_set_max_threads(cust_ctx, 0), 1))
  732. return 0;
  733. /* sequential startup */
  734. if (!TEST_int_eq(OSSL_set_max_threads(NULL, 1), 1))
  735. return 0;
  736. if (!TEST_uint64_t_eq(OSSL_get_max_threads(NULL), 1))
  737. return 0;
  738. if (!TEST_uint64_t_eq(OSSL_get_max_threads(cust_ctx), 0))
  739. return 0;
  740. for (i = 0; i < OSSL_NELEM(t); ++i) {
  741. local[0] = i + 1;
  742. t[i] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[0]);
  743. if (!TEST_ptr(t[i]))
  744. return 0;
  745. /*
  746. * pthread_join results in undefined behaviour if called on a joined
  747. * thread. We do not impose such restrictions, so it's up to us to
  748. * ensure that this does not happen (thread sanitizer will warn us
  749. * if we do).
  750. */
  751. if (!TEST_int_eq(ossl_crypto_thread_join(t[i], &retval[0]), 1))
  752. return 0;
  753. if (!TEST_int_eq(ossl_crypto_thread_join(t[i], &retval[0]), 1))
  754. return 0;
  755. if (!TEST_int_eq(retval[0], i + 1) || !TEST_int_eq(local[0], i + 2))
  756. return 0;
  757. if (!TEST_int_eq(ossl_crypto_thread_clean(t[i]), 1))
  758. return 0;
  759. t[i] = NULL;
  760. if (!TEST_int_eq(ossl_crypto_thread_clean(t[i]), 0))
  761. return 0;
  762. }
  763. /* parallel startup */
  764. if (!TEST_int_eq(OSSL_set_max_threads(NULL, OSSL_NELEM(t)), 1))
  765. return 0;
  766. for (i = 0; i < OSSL_NELEM(t); ++i) {
  767. local[i] = i + 1;
  768. t[i] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[i]);
  769. if (!TEST_ptr(t[i]))
  770. return 0;
  771. }
  772. for (i = 0; i < OSSL_NELEM(t); ++i) {
  773. if (!TEST_int_eq(ossl_crypto_thread_join(t[i], &retval[i]), 1))
  774. return 0;
  775. }
  776. for (i = 0; i < OSSL_NELEM(t); ++i) {
  777. if (!TEST_int_eq(retval[i], i + 1) || !TEST_int_eq(local[i], i + 2))
  778. return 0;
  779. if (!TEST_int_eq(ossl_crypto_thread_clean(t[i]), 1))
  780. return 0;
  781. }
  782. /* parallel startup, bottleneck */
  783. if (!TEST_int_eq(OSSL_set_max_threads(NULL, OSSL_NELEM(t) - 1), 1))
  784. return 0;
  785. for (i = 0; i < OSSL_NELEM(t); ++i) {
  786. local[i] = i + 1;
  787. t[i] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[i]);
  788. if (!TEST_ptr(t[i]))
  789. return 0;
  790. }
  791. for (i = 0; i < OSSL_NELEM(t); ++i) {
  792. if (!TEST_int_eq(ossl_crypto_thread_join(t[i], &retval[i]), 1))
  793. return 0;
  794. }
  795. for (i = 0; i < OSSL_NELEM(t); ++i) {
  796. if (!TEST_int_eq(retval[i], i + 1) || !TEST_int_eq(local[i], i + 2))
  797. return 0;
  798. if (!TEST_int_eq(ossl_crypto_thread_clean(t[i]), 1))
  799. return 0;
  800. }
  801. if (!TEST_int_eq(OSSL_set_max_threads(NULL, 0), 1))
  802. return 0;
  803. OSSL_LIB_CTX_free(cust_ctx);
  804. return 1;
  805. }
  806. #endif
  807. static uint32_t test_thread_native_multiple_joins_fn1(void *data)
  808. {
  809. return 0;
  810. }
  811. static uint32_t test_thread_native_multiple_joins_fn2(void *data)
  812. {
  813. ossl_crypto_thread_native_join((CRYPTO_THREAD *)data, NULL);
  814. return 0;
  815. }
  816. static uint32_t test_thread_native_multiple_joins_fn3(void *data)
  817. {
  818. ossl_crypto_thread_native_join((CRYPTO_THREAD *)data, NULL);
  819. return 0;
  820. }
  821. static int test_thread_native_multiple_joins(void)
  822. {
  823. CRYPTO_THREAD *t, *t1, *t2;
  824. t = ossl_crypto_thread_native_start(test_thread_native_multiple_joins_fn1, NULL, 1);
  825. t1 = ossl_crypto_thread_native_start(test_thread_native_multiple_joins_fn2, t, 1);
  826. t2 = ossl_crypto_thread_native_start(test_thread_native_multiple_joins_fn3, t, 1);
  827. if (!TEST_ptr(t) || !TEST_ptr(t1) || !TEST_ptr(t2))
  828. return 0;
  829. if (!TEST_int_eq(ossl_crypto_thread_native_join(t2, NULL), 1))
  830. return 0;
  831. if (!TEST_int_eq(ossl_crypto_thread_native_join(t1, NULL), 1))
  832. return 0;
  833. if (!TEST_int_eq(ossl_crypto_thread_native_clean(t2), 1))
  834. return 0;
  835. if (!TEST_int_eq(ossl_crypto_thread_native_clean(t1), 1))
  836. return 0;
  837. if (!TEST_int_eq(ossl_crypto_thread_native_clean(t), 1))
  838. return 0;
  839. return 1;
  840. }
  841. #endif
  842. typedef enum OPTION_choice {
  843. OPT_ERR = -1,
  844. OPT_EOF = 0,
  845. OPT_FIPS, OPT_CONFIG_FILE,
  846. OPT_TEST_ENUM
  847. } OPTION_CHOICE;
  848. const OPTIONS *test_get_options(void)
  849. {
  850. static const OPTIONS options[] = {
  851. OPT_TEST_OPTIONS_DEFAULT_USAGE,
  852. { "fips", OPT_FIPS, '-', "Test the FIPS provider" },
  853. { "config", OPT_CONFIG_FILE, '<',
  854. "The configuration file to use for the libctx" },
  855. { NULL }
  856. };
  857. return options;
  858. }
  859. int setup_tests(void)
  860. {
  861. OPTION_CHOICE o;
  862. char *datadir;
  863. while ((o = opt_next()) != OPT_EOF) {
  864. switch (o) {
  865. case OPT_FIPS:
  866. do_fips = 1;
  867. break;
  868. case OPT_CONFIG_FILE:
  869. config_file = opt_arg();
  870. break;
  871. case OPT_TEST_CASES:
  872. break;
  873. default:
  874. return 0;
  875. }
  876. }
  877. if (!TEST_ptr(datadir = test_get_argument(0)))
  878. return 0;
  879. privkey = test_mk_file_path(datadir, "rsakey.pem");
  880. if (!TEST_ptr(privkey))
  881. return 0;
  882. if (!TEST_ptr(global_lock = CRYPTO_THREAD_lock_new()))
  883. return 0;
  884. #ifdef TSAN_REQUIRES_LOCKING
  885. if (!TEST_ptr(tsan_lock = CRYPTO_THREAD_lock_new()))
  886. return 0;
  887. #endif
  888. /* Keep first to validate auto creation of default library context */
  889. ADD_TEST(test_multi_default);
  890. ADD_TEST(test_lock);
  891. ADD_TEST(test_once);
  892. ADD_TEST(test_thread_local);
  893. ADD_TEST(test_atomic);
  894. ADD_TEST(test_multi_load);
  895. ADD_TEST(test_multi_general_worker_default_provider);
  896. ADD_TEST(test_multi_general_worker_fips_provider);
  897. ADD_TEST(test_multi_fetch_worker);
  898. ADD_TEST(test_multi_shared_pkey);
  899. #ifndef OPENSSL_NO_DEPRECATED_3_0
  900. ADD_TEST(test_multi_downgrade_shared_pkey);
  901. #endif
  902. ADD_TEST(test_multi_load_unload_provider);
  903. ADD_TEST(test_obj_add);
  904. ADD_TEST(test_lib_ctx_load_config);
  905. #if !defined(OPENSSL_NO_DGRAM) && !defined(OPENSSL_NO_SOCK)
  906. ADD_TEST(test_bio_dgram_pair);
  907. #endif
  908. ADD_TEST(test_thread_reported_flags);
  909. #if defined(OPENSSL_THREADS)
  910. ADD_TEST(test_thread_native);
  911. ADD_TEST(test_thread_native_multiple_joins);
  912. #if !defined(OPENSSL_NO_DEFAULT_THREAD_POOL)
  913. ADD_TEST(test_thread_internal);
  914. #endif
  915. #endif
  916. return 1;
  917. }
  918. void cleanup_tests(void)
  919. {
  920. OPENSSL_free(privkey);
  921. #ifdef TSAN_REQUIRES_LOCKING
  922. CRYPTO_THREAD_lock_free(tsan_lock);
  923. #endif
  924. CRYPTO_THREAD_lock_free(global_lock);
  925. }