Commit eef0729ff9 for openssl.org

commit eef0729ff9100816ace87c2823c8560e935239ee
Author: Herman Malik <herman77malik@gmail.com>
Date:   Wed Mar 11 14:49:18 2026 -0700

    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 <nikolap@openssl.org>
    Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
    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 a08f52592c..b13d109a30 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<ret>.
 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<X509_STORE_up_ref(3)> and L<X509_STORE_free(3)>, and must ensure that
+all lookup operations have completed before the store is freed. See
+L<X509_STORE_new(3)/Thread Safety> for more discussion of the B<X509_STORE> 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<X509_LOOKUP_meth_set_get_by_subject(3)>,
-L<X509_LOOKUP_by_subject(3)>
+L<X509_LOOKUP_by_subject(3)>,
+L<X509_STORE_new(3)>

 =head1 COPYRIGHT

diff --git a/doc/man3/X509_STORE_new.pod b/doc/man3/X509_STORE_new.pod
index 9162080e0c..330cbe53c7 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<X509_STORE> 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<X509_STORE_add_cert(3)> or
+L<X509_STORE_add_crl(3)>, as well as looking up objects from the cache
+with L<X509_STORE_CTX_get_by_subject(3)> 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<configuration> functions (X509_STORE_set_flags(),
+X509_STORE_set_depth(), X509_STORE_set_purpose(), X509_STORE_set_trust(),
+and similar) are B<not> 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.