BUG/MAJOR: ssl/ocsp: lock the OCSP response around reads in the stapling callback
ssl_sock_ocsp_stapling_cbk() reads ocsp->response.area and
ocsp->response.data without any lock, while
ssl_sock_load_ocsp_response() -- called from the CLI "set ssl
ocsp-response" handler, the ocsp-update task and the reload path --
frees and replaces that buffer via chunk_dup(), also without any
synchronization:
A concurrent update frees the old area between the allocation and the
copy (heap-use-after-free read, confirmed under ASan as a READ of size
12548 in the callback's memcpy), or yields a torn read pairing the new
larger length with the old smaller area (linear over-read). Because the
copied bytes are handed to SSL_set_tlsext_status_ocsp_resp() and sent
to the TLS client in the status_request extension, freed or reused heap
contents can be disclosed to any remote client asking for a stapled
response during an update window; updates are periodic by default when
ocsp-update is enabled. A crash is the more likely practical outcome,
but the disclosure variant makes this heartbleed-class.
Let's take ocsp_tree_lock on both sides, which is the file's existing
idiom for accessing OCSP response contents (see
ssl_get_ocspresponse_detail()). The lock declaration is moved to the
top of the !OPENSSL_NO_OCSP section so that the callback can use it.
The critical section on the handshake path stays short (a validity
check plus a copy of a few KB), and allocating memory under this
spinlock is consistent with the existing "show ssl ocsp-response"
handler, which base64 encodes the response into a growable chunk while
holding the same lock.
This must be backported to all supported versions.