Skip to content

Commit 26ba634

Browse files
committed
add wolfSSL_Atomic_Ptr_CompareExchange(); mitigate race on ctx->privateKeyPKey in wolfSSL_CTX_get0_privatekey().
1 parent 6ff57b8 commit 26ba634

File tree

3 files changed

+73
-2
lines changed

3 files changed

+73
-2
lines changed

src/ssl.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7605,12 +7605,25 @@ WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx)
76057605
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
76067606
wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask);
76077607
#endif
7608-
res = wolfSSL_d2i_PrivateKey(type,
7609-
(WOLFSSL_EVP_PKEY**)&ctx->privateKeyPKey, &key,
7608+
res = wolfSSL_d2i_PrivateKey(type, NULL, &key,
76107609
(long)ctx->privateKey->length);
76117610
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
76127611
wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask);
76137612
#endif
7613+
if (res) {
7614+
#ifdef WOLFSSL_ATOMIC_OPS
7615+
WOLFSSL_EVP_PKEY *current_pkey = NULL;
7616+
if (! wolfSSL_Atomic_Ptr_CompareExchange(
7617+
(void **)&ctx->privateKeyPKey,
7618+
(void **)&current_pkey, res))
7619+
{
7620+
wolfSSL_EVP_PKEY_free(res);
7621+
res = current_pkey;
7622+
}
7623+
#else
7624+
ctx->privateKeyPKey = res;
7625+
#endif
7626+
}
76147627
}
76157628

76167629
return res;

wolfcrypt/src/wc_port.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,6 +1357,13 @@ int wolfSSL_Atomic_Uint_CompareExchange(
13571357
c, expected_i, new_i, 0 /* weak */, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE);
13581358
}
13591359

1360+
int wolfSSL_Atomic_Ptr_CompareExchange(
1361+
void **c, void **expected_ptr, void *new_ptr)
1362+
{
1363+
return __atomic_compare_exchange_n(
1364+
c, expected_ptr, new_ptr, 0 /* weak */, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE);
1365+
}
1366+
13601367
#else
13611368

13621369
/* Default C Implementation */
@@ -1444,6 +1451,17 @@ int wolfSSL_Atomic_Uint_CompareExchange(
14441451
c, expected_i, new_i, memory_order_seq_cst, memory_order_acquire);
14451452
}
14461453

1454+
int wolfSSL_Atomic_Ptr_CompareExchange(
1455+
void **c, void **expected_ptr, void *new_ptr)
1456+
{
1457+
/* use gcc-built-in __atomic_compare_exchange_n(), not
1458+
* atomic_compare_exchange_strong_explicit(), to sidestep _Atomic type
1459+
* requirements.
1460+
*/
1461+
return __atomic_compare_exchange_n(
1462+
c, expected_ptr, new_ptr, 0 /* weak */, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE);
1463+
}
1464+
14471465
#endif /* __cplusplus */
14481466

14491467
#elif defined(_MSC_VER)
@@ -1538,6 +1556,32 @@ int wolfSSL_Atomic_Uint_CompareExchange(
15381556
}
15391557
}
15401558

1559+
int wolfSSL_Atomic_Uint_CompareExchange(
1560+
void ** c, void **expected_ptr, void *new_ptr)
1561+
{
1562+
#ifdef _WIN64
1563+
LONG64 actual_ptr = InterlockedCompareExchange64
1564+
((LONG64 *)c, (LONG64)new_i, (LONG64)*expected_i);
1565+
if (actual_ptr == (LONG64)*expected_i) {
1566+
return 1;
1567+
}
1568+
else {
1569+
*expected_i = (void *)actual_ptr;
1570+
return 0;
1571+
}
1572+
#else /* !_WIN64 */
1573+
LONG actual_ptr = InterlockedCompareExchange
1574+
((LONG *)c, (LONG)new_i, (LONG)*expected_i);
1575+
if (actual_ptr == (LONG)*expected_i) {
1576+
return 1;
1577+
}
1578+
else {
1579+
*expected_i = (void *)actual_ptr;
1580+
return 0;
1581+
}
1582+
#endif /* !_WIN64 */
1583+
}
1584+
15411585
#endif
15421586

15431587
#endif /* WOLFSSL_ATOMIC_OPS */

wolfssl/wolfcrypt/wc_port.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,8 @@
586586
wolfSSL_Atomic_Uint* c, unsigned int i);
587587
WOLFSSL_API int wolfSSL_Atomic_Uint_CompareExchange(
588588
wolfSSL_Atomic_Uint* c, unsigned int *expected_i, unsigned int new_i);
589+
WOLFSSL_API int wolfSSL_Atomic_Ptr_CompareExchange(
590+
void** c, void **expected_ptr, void *new_ptr);
589591
#else
590592
/* Code using these fallback implementations in non-SINGLE_THREADED builds
591593
* needs to arrange its own explicit fallback to int for wolfSSL_Atomic_Int
@@ -623,6 +625,18 @@
623625
return 0;
624626
}
625627
}
628+
static WC_INLINE int wolfSSL_Atomic_Ptr_CompareExchange(
629+
void **c, void *expected_ptr, void *new_ptr)
630+
{
631+
if (*(char **)c == *(char **)expected_ptr) {
632+
*(char **)c = (char *)new_ptr;
633+
return 1;
634+
}
635+
else {
636+
*(char **)expected_ptr = *(char **)c;
637+
return 0;
638+
}
639+
}
626640
static WC_INLINE unsigned int wolfSSL_Atomic_Uint_FetchAdd(
627641
unsigned int *c, unsigned int i)
628642
{

0 commit comments

Comments
 (0)