Lock globalRNGMutex around all shared globalRNG access#10824
Lock globalRNGMutex around all shared globalRNG access#10824yosuke-wolfssl wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR strengthens thread safety in the OpenSSL-compat RNG path by extending the existing globalRNGMutex locking discipline to all remaining operations that touch the shared static WC_RNG globalRNG, preventing races in DRBG/seed state when called concurrently.
Changes:
- Add
globalRNGMutexlocking aroundglobalRNGoperations inwolfSSL_RAND_write_file,wolfSSL_RAND_egd, andwolfSSL_RAND_poll. - Add
globalRNGMutexlocking around detached S/MIME boundary generation inwolfSSL_SMIME_write_PKCS7.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/ssl.c | Adds missing globalRNGMutex locking around reseed/seed/generate operations on the shared globalRNG. |
| src/ssl_p7p12.c | Locks globalRNGMutex while generating the detached S/MIME boundary using globalRNG. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ffef7a3 to
b9efc8e
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #10824
Scan targets checked: wolfssl-bugs, wolfssl-src
No new issues found in the changed files. ✅
a339c35 to
d0e161d
Compare
dgarske
left a comment
There was a problem hiding this comment.
Skoll Multi-Scan Review
Modes: review + review-securityOverall recommendation: COMMENT
Findings: 3 total — 1 posted, 2 skipped
1 finding(s) posted as inline comments (see file-level comments below)
Posted findings
- [Low] [review] Buffer-wipe hardening (ForceZero size 1024) is bundled with a locking-only PR —
src/ssl.c:15757-15759
Skipped findings
- [Low]
RAND_poll now holds globalRNGMutex across the potentially-blocking wc_GenerateSeed (intentional critical-section widening) - [Low]
No concurrency/thread-safety regression test for the newly locked paths
Review generated by Skoll
| } | ||
| } | ||
| ForceZero(buf, (word32)bytes); | ||
| /* wipe the whole buffer, not just (word32)bytes: error paths set |
There was a problem hiding this comment.
🔵 [Low] Buffer-wipe hardening (ForceZero size 1024) is bundled with a locking-only PR · style
The change from ForceZero(buf, (word32)bytes) to ForceZero(buf, 1024) is a genuine and correct improvement: on error paths bytes is set to 0, so the previous code left generated random data un-wiped, and it also brings the wipe into agreement with the wc_MemZero_Add(..., buf, bytes) / wc_MemZero_Check(buf, sizeof(buf)) region under WOLFSSL_CHECK_MEM_ZERO. The buffer is always exactly 1024 bytes in both the small-stack and non-small-stack paths, so the fixed size is safe. Two minor observations: (1) this hardening is unrelated to the PR's stated purpose (mutex locking) and could arguably be a separate commit; (2) the literal 1024 repeats the same magic number already used at the XMALLOC and bytes = 1024 sites in this function.
Fix: Keep the fix. Optionally introduce a local named constant (e.g. #define RAND_WRITE_FILE_SZ 1024) shared by the XMALLOC, bytes init, and ForceZero to avoid the repeated magic number.
There was a problem hiding this comment.
Fixed with configurable macro WOLFSSL_RAND_WRITE_FILE_BUF_SZ.
| ForceZero(buf, (word32)bytes); | ||
| /* wipe the whole buffer, not just (word32)bytes: error paths set | ||
| * bytes = 0 but the buffer may still hold generated random data */ | ||
| ForceZero(buf, 1024); |
There was a problem hiding this comment.
Please cleanup the hard coded 1024 in this function and make overridable macro. Thanks! Check to see if there is already one.
There was a problem hiding this comment.
Fixed with new macro WOLFSSL_RAND_WRITE_FILE_BUF_SZ.
Other existing macros 1024 are semantically unrelated, so I prepared new one.
d0e161d to
768a980
Compare
|
tps-staticmemory test would be fixed on PR #10868 |
Description
The OpenSSL-compat layer shares a single static
WC_RNG globalRNGwhoseHash-DRBG state is not internally thread-safe. The canonical access pattern
(
wolfSSL_RAND_bytes) holdsglobalRNGMutexfor the entire duration of anyoperation on
globalRNG. Several sibling functions mutated the sameglobalRNGwithout taking the lock, so concurrent callers — or onerunning alongside a lock-holding
RAND_bytes/RAND_addcaller — could raceon the shared DRBG V/C/reseed-counter and seed state, corrupting the DRBG and
the randomness it yields to compat consumers (IVs, nonces, keys).
This PR extends the existing
globalRNGMutexdiscipline to every remainingunprotected access.
Addressed by f_6555 and f_6556.
Changes
src/ssl.cwolfSSL_RAND_write_file: acquireglobalRNGMutexaroundwc_RNG_GenerateBlock(&globalRNG, ...), unlocking before the file I/O tokeep the critical section minimal.
wolfSSL_RAND_egd: lock around thewc_RNG_DRBG_Reseed(&globalRNG, ...)of the collected EGD entropy.
wolfSSL_RAND_poll: hold the lock from beforewc_GenerateSeed(&globalRNG.seed, ...)(previously an unlocked write to
globalRNG.seed) throughwc_RNG_DRBG_Reseed, unlocking on every path (including theHAVE_INTEL_RDRANDand no-HASHDRBG branches). Added a comment noting thelock intentionally covers
wc_GenerateSeedso the scope is not narrowedback later.
src/ssl_p7p12.cwolfSSL_SMIME_write_PKCS7: lock around thewc_RNG_GenerateBlock(&globalRNG, ...)that generates the detached S/MIME MIME boundary, following the function's
existing
ret > 0fallthrough style.Notes
wolfSSL_RAND_pollis called bywolfSSL_RAND_bytesonly after thatfunction releases
globalRNGMutex(and it re-acquires it afterward), sohaving
RAND_polltake the lock itself does not self-deadlock.globalRNGMutexis in scope forssl_p7p12.cbecause it is#includedinto
ssl.cafter the mutex'sstaticdefinition, within the sameOPENSSL_EXTRA/HAVE_GLOBAL_RNGcontext.Testing
./configure --enable-allbuilt under-fsanitize=address,undefined -fno-omit-frame-pointer; full./tests/unit.testpasses (exit 0),including
test_wolfSSL_RAND_poll, theossl_randgroup, andtest_wolfSSL_SMIME_write_PKCS7.