This is an automated email from the ASF dual-hosted git repository.
wkaras pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 6bf342ba36 Fix for OpenSSL 3.2+. (#11501)
6bf342ba36 is described below
commit 6bf342ba362a42786b9efcb0d4d554f725643a8d
Author: Walt Karas <[email protected]>
AuthorDate: Tue Jul 16 14:32:37 2024 -0400
Fix for OpenSSL 3.2+. (#11501)
It seems BIO user data is no longer set to nullptr.
---
CMakeLists.txt | 3 +
include/tscore/ink_config.h.cmake.in | 3 +
src/iocore/net/BIO_fastopen.cc | 133 +++++++++++++++++++++++++++++++----
src/iocore/net/BIO_fastopen.h | 7 +-
src/iocore/net/SSLNetVConnection.cc | 5 +-
5 files changed, 128 insertions(+), 23 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4271858dfa..5cbf1d6fd0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -451,6 +451,9 @@ check_symbol_exists(BIO_meth_new "openssl/bio.h"
HAVE_BIO_METH_NEW)
check_symbol_exists(BIO_set_data "openssl/bio.h" HAVE_BIO_SET_DATA)
check_symbol_exists(BIO_get_data "openssl/bio.h" HAVE_BIO_GET_DATA)
check_symbol_exists(BIO_get_shutdown "openssl/bio.h" HAVE_BIO_GET_SHUTDOWN)
+check_symbol_exists(BIO_get_ex_new_index "openssl/bio.h"
HAVE_BIO_GET_EX_NEW_INDEX)
+check_symbol_exists(BIO_get_ex_data "openssl/bio.h" HAVE_BIO_GET_EX_DATA)
+check_symbol_exists(BIO_set_ex_data "openssl/bio.h" HAVE_BIO_SET_EX_DATA)
check_symbol_exists(BIO_meth_get_ctrl "openssl/bio.h" HAVE_BIO_METH_GET_CTRL)
check_symbol_exists(BIO_meth_get_create "openssl/bio.h"
HAVE_BIO_METH_GET_CREATE)
check_symbol_exists(BIO_meth_get_destroy "openssl/bio.h"
HAVE_BIO_METH_GET_DESTROY)
diff --git a/include/tscore/ink_config.h.cmake.in
b/include/tscore/ink_config.h.cmake.in
index 260ea7a244..fe85c656c5 100644
--- a/include/tscore/ink_config.h.cmake.in
+++ b/include/tscore/ink_config.h.cmake.in
@@ -80,6 +80,9 @@
#cmakedefine HAVE_BIO_SET_DATA 1
#cmakedefine HAVE_BIO_GET_DATA 1
#cmakedefine HAVE_BIO_GET_SHUTDOWN 1
+#cmakedefine HAVE_BIO_GET_EX_NEW_INDEX 1
+#cmakedefine HAVE_BIO_GET_EX_DATA 1
+#cmakedefine HAVE_BIO_SET_EX_DATA 1
#cmakedefine HAVE_BIO_METH_GET_CTRL 1
#cmakedefine HAVE_BIO_METH_GET_CREATE 1
#cmakedefine HAVE_BIO_METH_GET_DESTROY 1
diff --git a/src/iocore/net/BIO_fastopen.cc b/src/iocore/net/BIO_fastopen.cc
index ac2a9e38b7..fd9ea9dd9c 100644
--- a/src/iocore/net/BIO_fastopen.cc
+++ b/src/iocore/net/BIO_fastopen.cc
@@ -21,12 +21,116 @@
* limitations under the License.
*/
+#include <openssl/opensslv.h>
+
#include "P_Net.h"
#include "iocore/eventsystem/SocketManager.h"
#include "tscore/ink_assert.h"
+#include "tscore/ink_config.h"
#include "BIO_fastopen.h"
+#if defined(BORINGLIKE)
+#error
+#elif defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
+#define BORINGLIKE 1
+#else
+#define BORINGLIKE 0
+#endif
+
+namespace
+{
+
+#if defined(HAVE_BIO_GET_EX_NEW_INDEX) && defined(HAVE_BIO_GET_EX_DATA) &&
defined(HAVE_BIO_SET_EX_DATA)
+
+class ExData
+{
+public:
+ // Pseudo-namespace
+ ExData() = delete;
+
+ static int
+ idx()
+ {
+ static int idx_ = []() -> int {
+ int i = BIO_get_ex_new_index(0, nullptr, _new, _dup, _free);
+ ink_release_assert(i >= 0);
+ return i;
+ }();
+ return idx_;
+ }
+
+private:
+#if BORINGLIKE
+ static constexpr CRYPTO_EX_unused *_new{nullptr};
+#else
+ static void
+ _new(void * /* parent */, void * /* ptr */, CRYPTO_EX_DATA *ad, int idx_,
long /* argl */, void * /* argp */)
+ {
+ ink_release_assert(CRYPTO_set_ex_data(ad, idx_, nullptr) == 1);
+ }
+#endif
+
+#if BORINGLIKE
+ static void
+ _free(void * /* parent */, void * /* ptr */, CRYPTO_EX_DATA * /* ad */, int
/* idx_ */, long /* argl */, void * /* argp */)
+ {
+ }
+#else
+ static void
+ _free(void * /* parent */, void * /* ptr */, CRYPTO_EX_DATA *ad, int idx_,
long /* argl */, void * /* argp */)
+ {
+ ink_release_assert(CRYPTO_set_ex_data(ad, idx_, nullptr) == 1);
+ }
+#endif
+
+#if BORINGLIKE || (OPENSSL_VERSION_MAJOR >= 3)
+ using _Type_from_d = void **;
+#else
+ using _Type_from_d = void *;
+#endif
+
+ static int
+ _dup(CRYPTO_EX_DATA * /* to */, const CRYPTO_EX_DATA * /* from */,
_Type_from_d /* from_d */, int /* idx */, long /* argl */,
+ void * /* argp */)
+ {
+ ink_assert(false);
+ return 0;
+ }
+};
+
+inline void
+set_dest_addr_for_bio(BIO *b, void *dest_addr)
+{
+ ink_assert(BIO_set_ex_data(b, ExData::idx(), dest_addr) == 1);
+}
+
+inline void *
+get_dest_addr_for_bio(BIO *b)
+{
+ return BIO_get_ex_data(b, ExData::idx());
+}
+
+#else // no BIO ex data in SSL library
+
+// Fall back on the krufty way this was done using older SSL libraries.
+
+inline void
+set_dest_addr_for_bio(BIO *b, void *dest_addr)
+{
+ BIO_set_data(b, dest_addr);
+}
+
+inline void *
+get_dest_addr_for_bio(BIO *b)
+{
+ return BIO_get_data(b);
+}
+
+#endif
+
+} // end anonymous namespace
+
// For BoringSSL, which for some reason doesn't have this function.
// (In BoringSSL, sock_read() and sock_write() use the internal
// bio_fd_non_fatal_error() instead.) #1437
@@ -113,20 +217,20 @@ fastopen_bwrite(BIO *bio, const char *in, int insz)
int fd = BIO_get_fd(bio, nullptr);
ink_assert(fd != NO_FD);
- if (BIO_get_data(bio)) {
+ void *dst_void = get_dest_addr_for_bio(bio);
+ if (dst_void) {
+ auto dst = static_cast<sockaddr *>(dst_void);
// On the first write only, make a TFO request if TFO is enabled.
// The best documentation on the behavior of the Linux API is in
// RFC 7413. If we get EINPROGRESS it means that the SYN has been
// sent without data and we should retry.
- const sockaddr *dst = reinterpret_cast<const sockaddr
*>(BIO_get_data(bio));
-
Metrics::Counter::increment(net_rsb.fastopen_attempts);
err = SocketManager::sendto(fd, (void *)in, insz, MSG_FASTOPEN, dst,
ats_ip_size(dst));
if (err >= 0) {
Metrics::Counter::increment(net_rsb.fastopen_successes);
}
- BIO_set_data(bio, nullptr);
+ set_dest_addr_for_bio(bio, nullptr);
} else {
err = SocketManager::write(fd, (void *)in, insz);
}
@@ -164,21 +268,14 @@ fastopen_bread(BIO *bio, char *out, int outsz)
return err < 0 ? -1 : err;
}
+#ifndef HAVE_BIO_METH_NEW
+
static long
fastopen_ctrl(BIO *bio, int cmd, long larg, void *ptr)
{
- switch (cmd) {
- case BIO_C_SET_CONNECT:
- // We only support BIO_set_conn_address(), which sets a sockaddr.
- ink_assert(larg == 2);
- BIO_set_data(bio, ptr);
- return 0;
- }
-
return BIO_meth_get_ctrl(const_cast<BIO_METHOD *>(BIO_s_socket()))(bio, cmd,
larg, ptr);
}
-#ifndef HAVE_BIO_METH_NEW
static const BIO_METHOD fastopen_methods[] = {
{
.type = BIO_TYPE_SOCKET,
@@ -193,12 +290,12 @@ static const BIO_METHOD fastopen_methods[] = {
.callback_ctrl = nullptr,
}
};
-#else
+#else // defined(HAVE_BIO_METH_NEW)
static const BIO_METHOD *fastopen_methods = [] {
BIO_METHOD *methods = BIO_meth_new(BIO_TYPE_SOCKET, "fastopen");
BIO_meth_set_write(methods, fastopen_bwrite);
BIO_meth_set_read(methods, fastopen_bread);
- BIO_meth_set_ctrl(methods, fastopen_ctrl);
+ BIO_meth_set_ctrl(methods, BIO_meth_get_ctrl(const_cast<BIO_METHOD
*>(BIO_s_socket())));
BIO_meth_set_create(methods, fastopen_create);
BIO_meth_set_destroy(methods, fastopen_destroy);
return methods;
@@ -210,3 +307,9 @@ BIO_s_fastopen()
{
return fastopen_methods;
}
+
+void
+BIO_fastopen_set_dest_addr(BIO *bio, const sockaddr *dest_addr)
+{
+ set_dest_addr_for_bio(bio, const_cast<sockaddr *>(dest_addr));
+}
diff --git a/src/iocore/net/BIO_fastopen.h b/src/iocore/net/BIO_fastopen.h
index ce42e3be42..b949953daa 100644
--- a/src/iocore/net/BIO_fastopen.h
+++ b/src/iocore/net/BIO_fastopen.h
@@ -29,8 +29,5 @@
// Return a BIO_METHOD for a socket BIO that implements TCP Fast Open.
const BIO_METHOD *BIO_s_fastopen();
-// OpenSSL 1.0.2h has BIO_set_conn_ip(), but master has
BIO_set_conn_address(). Use
-// the API from master since it makes more sense.
-#if !defined(BIO_set_conn_address)
-#define BIO_set_conn_address(b, addr) BIO_ctrl(b, BIO_C_SET_CONNECT, 2, (char
*)addr)
-#endif
+// Set destination address for a BIO for a fastopen TCP socket where the local
host is the client.
+void BIO_fastopen_set_dest_addr(BIO *bio, const sockaddr *dest_addr);
diff --git a/src/iocore/net/SSLNetVConnection.cc
b/src/iocore/net/SSLNetVConnection.cc
index ca89894be0..5ebb705f0e 100644
--- a/src/iocore/net/SSLNetVConnection.cc
+++ b/src/iocore/net/SSLNetVConnection.cc
@@ -212,9 +212,8 @@ SSLNetVConnection::_make_ssl_connection(SSL_CTX *ctx)
BIO *bio = BIO_new(const_cast<BIO_METHOD *>(BIO_s_fastopen()));
BIO_set_fd(bio, this->get_socket(), BIO_NOCLOSE);
- if (this->options.f_tcp_fastopen) {
- BIO_set_conn_address(bio, this->get_remote_addr());
- }
+ BIO_fastopen_set_dest_addr(bio,
+ this->options.f_tcp_fastopen ?
this->get_remote_addr() : static_cast<const sockaddr *>(nullptr));
SSL_set_bio(ssl, bio, bio);
} else {