From: Herman Malik Date: Wed, 11 Mar 2026 21:49:18 +0000 (-0700) Subject: doc: clarify X509_STORE thread safety and lifetime contract X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eef0729ff9100816ace87c2823c8560e935239ee;p=thirdparty%2Fopenssl.git doc: clarify X509_STORE thread safety and lifetime contract Improve the description of X509_STORE_lock() in X509_STORE_new.pod to emphasize it acquires an exclusive write lock. Add a NOTES section to X509_STORE_new.pod covering which operations are internally thread-safe and which are not, as well as documentation on lifetime management and reference counting. Add a NOTES section to X509_STORE_CTX_get_by_subject.pod explaining that the store's internal lock is released before the found object's reference count is incremented, so the caller must ensure the store outlives the lookup. Clarify the reference counting and the caller's responsibilities. Remove internal details for conciseness. Related to #30310 Reviewed-by: Nikola Pajkovsky Reviewed-by: Eugene Syromiatnikov MergeDate: Fri Apr 3 15:00:55 2026 (Merged from https://github.com/openssl/openssl/pull/30382) --- diff --git a/doc/man3/X509_STORE_CTX_get_by_subject.pod b/doc/man3/X509_STORE_CTX_get_by_subject.pod index a08f52592c4..b13d109a301 100644 --- a/doc/man3/X509_STORE_CTX_get_by_subject.pod +++ b/doc/man3/X509_STORE_CTX_get_by_subject.pod @@ -28,6 +28,17 @@ stores the looked up object in I. X509_STORE_CTX_get_obj_by_subject() is like X509_STORE_CTX_get_by_subject() but returns the found object on success, else NULL. +=head1 NOTES + +These functions are safe to use in a multithreaded environment and with +lookup functions on the same store. + +Applications sharing a store across threads should manage its lifetime with +L and L, and must ensure that +all lookup operations have completed before the store is freed. See +L for more discussion of the B threading +model. + =head1 RETURN VALUES X509_STORE_CTX_get_by_subject() returns 1 if the lookup was successful, else 0. @@ -37,7 +48,8 @@ X509_STORE_CTX_get_obj_by_subject() returns an object on success, else NULL. =head1 SEE ALSO L, -L +L, +L =head1 COPYRIGHT diff --git a/doc/man3/X509_STORE_new.pod b/doc/man3/X509_STORE_new.pod index 9162080e0cf..330cbe53c76 100644 --- a/doc/man3/X509_STORE_new.pod +++ b/doc/man3/X509_STORE_new.pod @@ -23,12 +23,40 @@ The X509_STORE_new() function returns a new X509_STORE. X509_STORE_up_ref() increments the reference count associated with the X509_STORE object. -X509_STORE_lock() locks the store from modification by other threads, -X509_STORE_unlock() unlocks it. +X509_STORE_lock() locks the store from reads and writes by other threads, +and X509_STORE_unlock() unlocks it. Not all operations require locking +the store, see the notes on thread safety below. -X509_STORE_free() frees up a single X509_STORE object. +X509_STORE_free() decrements the reference count of the X509_STORE object. +The store's memory is only freed when its reference count drops to +zero. If the argument is NULL, nothing is done. +=head1 NOTES + +=head2 Thread Safety + +When an B is shared across multiple threads, each thread or +component that holds a pointer to it should call X509_STORE_up_ref() to +acquire a reference, and release the reference with X509_STORE_free() when +done. + +Adding certificates or CRLs, for example L or +L, as well as looking up objects from the cache +with L are safe to call concurrently +from multiple threads on the same store without external synchronization, +provided the ownership to the X509_STORE is obtained by acquiring a +reference in advance. + +Store I functions (X509_STORE_set_flags(), +X509_STORE_set_depth(), X509_STORE_set_purpose(), X509_STORE_set_trust(), +and similar) are B safe to call concurrently with any other operation +on the same store; the store must be fully configured before being shared +with other threads. + +One useful pattern is having a single owner thread that calls +X509_STORE_free() only after joining with all threads that use the store. + =head1 RETURN VALUES X509_STORE_new() returns a newly created X509_STORE or NULL if the call fails.