Skip to content

Commit c683ee4

Browse files
ezelkow1ywkaras
andauthored
92x #11501 patch (#11882)
* Fix for OpenSSL 3.2+. (#11501) It seems BIO user data is no longer set to nullptr. (cherry picked from commit 6bf342b) ----- Still needs configure modifications for non-Cmake build * Fix socket def * Chris' make fixes --------- Co-authored-by: Walt Karas <[email protected]>
1 parent a0d49dd commit c683ee4

File tree

6 files changed

+157
-23
lines changed

6 files changed

+157
-23
lines changed

build/crypto.m4

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,3 +450,32 @@ AC_DEFUN([TS_CHECK_VERIFY_CERT_STORE], [
450450
451451
AC_SUBST(has_verify_cert_store)
452452
])
453+
454+
AC_DEFUN([TS_CHECK_BIO_GET_EX_NEW_INDEX], [
455+
_saved_LIBS=$LIBS
456+
457+
TS_ADDTO(LIBS, [$OPENSSL_LIBS])
458+
bio_get_ex_new_index_check=no
459+
has_verify_cert_store=0
460+
AC_MSG_CHECKING([for BIO_get_ex_new_index macro])
461+
AC_COMPILE_IFELSE(
462+
[AC_LANG_PROGRAM([[#include <openssl/ssl.h>]],
463+
[[
464+
#ifndef BIO_get_ex_new_index
465+
#error
466+
#endif
467+
]])
468+
],
469+
[
470+
bio_get_ex_new_index_check=yes
471+
have_bio_get_ex_new_index=1
472+
],
473+
[]
474+
)
475+
AC_MSG_RESULT([$bio_get_ex_new_index_check])
476+
477+
LIBS=$_saved_LIBS
478+
479+
480+
AC_SUBST(have_bio_get_ex_new_index)
481+
])

configure.ac

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,8 +1354,12 @@ AC_CHECK_FUNCS([ \
13541354
SHA256_Init \
13551355
MD5_Init \
13561356
SSL_SESSION_dup \
1357+
BIO_get_ex_data \
1358+
BIO_set_ex_data \
13571359
])
13581360

1361+
TS_CHECK_BIO_GET_EX_NEW_INDEX
1362+
13591363
AC_CHECK_FUNC([ASN1_STRING_get0_data], [],
13601364
[AC_DEFINE([ASN1_STRING_get0_data], [ASN1_STRING_data], [Added in OpenSSL 1.1])])
13611365

include/tscore/ink_config.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@
8383
#define TS_HAS_TLS_EARLY_DATA @has_tls_early_data@
8484
#define TS_HAS_TLS_SESSION_TICKET @has_tls_session_ticket@
8585
#define TS_HAS_VERIFY_CERT_STORE @has_verify_cert_store@
86+
#define TS_HAS_VERIFY_CERT_STORE @has_verify_cert_store@
87+
#define HAVE_BIO_GET_EX_NEW_INDEX @have_bio_get_ex_new_index@
8688

8789
#define TS_USE_HRW_GEOIP @use_hrw_geoip@
8890
#define TS_USE_HRW_MAXMINDDB @use_hrw_maxminddb@

iocore/net/BIO_fastopen.cc

Lines changed: 118 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,115 @@
2121
* limitations under the License.
2222
*/
2323

24+
#include <openssl/opensslv.h>
25+
2426
#include "P_Net.h"
2527
#include "I_SocketManager.h"
2628
#include "tscore/ink_assert.h"
29+
#include "tscore/ink_config.h"
2730

2831
#include "BIO_fastopen.h"
2932

33+
#if defined(BORINGLIKE)
34+
#error
35+
#elif defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
36+
#define BORINGLIKE 1
37+
#else
38+
#define BORINGLIKE 0
39+
#endif
40+
41+
namespace
42+
{
43+
#if defined(HAVE_BIO_GET_EX_NEW_INDEX) && defined(HAVE_BIO_GET_EX_DATA) && defined(HAVE_BIO_SET_EX_DATA)
44+
45+
class ExData
46+
{
47+
public:
48+
// Pseudo-namespace
49+
ExData() = delete;
50+
51+
static int
52+
idx()
53+
{
54+
static int idx_ = []() -> int {
55+
int i = BIO_get_ex_new_index(0, nullptr, _new, _dup, _free);
56+
ink_release_assert(i >= 0);
57+
return i;
58+
}();
59+
return idx_;
60+
}
61+
62+
private:
63+
#if BORINGLIKE
64+
static constexpr CRYPTO_EX_unused *_new{nullptr};
65+
#else
66+
static void
67+
_new(void * /* parent */, void * /* ptr */, CRYPTO_EX_DATA *ad, int idx_, long /* argl */, void * /* argp */)
68+
{
69+
ink_release_assert(CRYPTO_set_ex_data(ad, idx_, nullptr) == 1);
70+
}
71+
#endif
72+
73+
#if BORINGLIKE
74+
static void
75+
_free(void * /* parent */, void * /* ptr */, CRYPTO_EX_DATA * /* ad */, int /* idx_ */, long /* argl */, void * /* argp */)
76+
{
77+
}
78+
#else
79+
static void
80+
_free(void * /* parent */, void * /* ptr */, CRYPTO_EX_DATA *ad, int idx_, long /* argl */, void * /* argp */)
81+
{
82+
ink_release_assert(CRYPTO_set_ex_data(ad, idx_, nullptr) == 1);
83+
}
84+
#endif
85+
86+
#if BORINGLIKE || (OPENSSL_VERSION_MAJOR >= 3)
87+
using _Type_from_d = void **;
88+
#else
89+
using _Type_from_d = void *;
90+
#endif
91+
92+
static int
93+
_dup(CRYPTO_EX_DATA * /* to */, const CRYPTO_EX_DATA * /* from */, _Type_from_d /* from_d */, int /* idx */, long /* argl */,
94+
void * /* argp */)
95+
{
96+
ink_assert(false);
97+
return 0;
98+
}
99+
};
100+
101+
inline void
102+
set_dest_addr_for_bio(BIO *b, void *dest_addr)
103+
{
104+
ink_assert(BIO_set_ex_data(b, ExData::idx(), dest_addr) == 1);
105+
}
106+
107+
inline void *
108+
get_dest_addr_for_bio(BIO *b)
109+
{
110+
return BIO_get_ex_data(b, ExData::idx());
111+
}
112+
113+
#else // no BIO ex data in SSL library
114+
115+
// Fall back on the krufty way this was done using older SSL libraries.
116+
117+
inline void
118+
set_dest_addr_for_bio(BIO *b, void *dest_addr)
119+
{
120+
BIO_set_data(b, dest_addr);
121+
}
122+
123+
inline void *
124+
get_dest_addr_for_bio(BIO *b)
125+
{
126+
return BIO_get_data(b);
127+
}
128+
129+
#endif
130+
131+
} // end anonymous namespace
132+
30133
// For BoringSSL, which for some reason doesn't have this function.
31134
// (In BoringSSL, sock_read() and sock_write() use the internal
32135
// bio_fd_non_fatal_error() instead.) #1437
@@ -113,13 +216,14 @@ fastopen_bwrite(BIO *bio, const char *in, int insz)
113216
int fd = BIO_get_fd(bio, nullptr);
114217
ink_assert(fd != NO_FD);
115218

116-
if (BIO_get_data(bio)) {
219+
void *dst_void = get_dest_addr_for_bio(bio);
220+
if (dst_void) {
221+
auto dst = static_cast<sockaddr *>(dst_void);
117222
// On the first write only, make a TFO request if TFO is enabled.
118223
// The best documentation on the behavior of the Linux API is in
119224
// RFC 7413. If we get EINPROGRESS it means that the SYN has been
120225
// sent without data and we should retry.
121-
const sockaddr *dst = reinterpret_cast<const sockaddr *>(BIO_get_data(bio));
122-
ProxyMutex *mutex = this_ethread()->mutex.get();
226+
ProxyMutex *mutex = this_ethread()->mutex.get();
123227

124228
NET_INCREMENT_DYN_STAT(net_fastopen_attempts_stat);
125229

@@ -128,7 +232,7 @@ fastopen_bwrite(BIO *bio, const char *in, int insz)
128232
NET_INCREMENT_DYN_STAT(net_fastopen_successes_stat);
129233
}
130234

131-
BIO_set_data(bio, nullptr);
235+
set_dest_addr_for_bio(bio, nullptr);
132236
} else {
133237
err = socketManager.write(fd, (void *)in, insz);
134238
}
@@ -166,21 +270,14 @@ fastopen_bread(BIO *bio, char *out, int outsz)
166270
return err < 0 ? -1 : err;
167271
}
168272

273+
#ifndef HAVE_BIO_METH_NEW
274+
169275
static long
170276
fastopen_ctrl(BIO *bio, int cmd, long larg, void *ptr)
171277
{
172-
switch (cmd) {
173-
case BIO_C_SET_CONNECT:
174-
// We only support BIO_set_conn_address(), which sets a sockaddr.
175-
ink_assert(larg == 2);
176-
BIO_set_data(bio, ptr);
177-
return 0;
178-
}
179-
180278
return BIO_meth_get_ctrl(const_cast<BIO_METHOD *>(BIO_s_socket()))(bio, cmd, larg, ptr);
181279
}
182280

183-
#ifndef HAVE_BIO_METH_NEW
184281
static const BIO_METHOD fastopen_methods[] = {{
185282
.type = BIO_TYPE_SOCKET,
186283
.name = "fastopen",
@@ -193,12 +290,12 @@ static const BIO_METHOD fastopen_methods[] = {{
193290
.destroy = fastopen_destroy,
194291
.callback_ctrl = nullptr,
195292
}};
196-
#else
293+
#else // defined(HAVE_BIO_METH_NEW)
197294
static const BIO_METHOD *fastopen_methods = [] {
198295
BIO_METHOD *methods = BIO_meth_new(BIO_TYPE_SOCKET, "fastopen");
199296
BIO_meth_set_write(methods, fastopen_bwrite);
200297
BIO_meth_set_read(methods, fastopen_bread);
201-
BIO_meth_set_ctrl(methods, fastopen_ctrl);
298+
BIO_meth_set_ctrl(methods, BIO_meth_get_ctrl(const_cast<BIO_METHOD *>(BIO_s_socket())));
202299
BIO_meth_set_create(methods, fastopen_create);
203300
BIO_meth_set_destroy(methods, fastopen_destroy);
204301
return methods;
@@ -210,3 +307,9 @@ BIO_s_fastopen()
210307
{
211308
return fastopen_methods;
212309
}
310+
311+
void
312+
BIO_fastopen_set_dest_addr(BIO *bio, const sockaddr *dest_addr)
313+
{
314+
set_dest_addr_for_bio(bio, const_cast<sockaddr *>(dest_addr));
315+
}

iocore/net/BIO_fastopen.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,5 @@
2828
// Return a BIO_METHOD for a socket BIO that implements TCP Fast Open.
2929
const BIO_METHOD *BIO_s_fastopen();
3030

31-
// OpenSSL 1.0.2h has BIO_set_conn_ip(), but master has BIO_set_conn_address(). Use
32-
// the API from master since it makes more sense.
33-
#if !defined(BIO_set_conn_address)
34-
#define BIO_set_conn_address(b, addr) BIO_ctrl(b, BIO_C_SET_CONNECT, 2, (char *)addr)
35-
#endif
31+
// Set destination address for a BIO for a fastopen TCP socket where the local host is the client.
32+
void BIO_fastopen_set_dest_addr(BIO *bio, const sockaddr *dest_addr);

iocore/net/SSLNetVConnection.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,8 @@ SSLNetVConnection::_make_ssl_connection(SSL_CTX *ctx)
162162
BIO *bio = BIO_new(const_cast<BIO_METHOD *>(BIO_s_fastopen()));
163163
BIO_set_fd(bio, this->get_socket(), BIO_NOCLOSE);
164164

165-
if (this->options.f_tcp_fastopen) {
166-
BIO_set_conn_address(bio, this->get_remote_addr());
167-
}
165+
BIO_fastopen_set_dest_addr(bio,
166+
this->options.f_tcp_fastopen ? this->get_remote_addr() : static_cast<const sockaddr *>(nullptr));
168167

169168
SSL_set_bio(ssl, bio, bio);
170169
} else {

0 commit comments

Comments
 (0)