path: root/ext/openssl
diff options
authorKazuki Yamaguchi <>2021-10-14 15:53:00 +0900
committerKazuki Yamaguchi <>2021-10-16 18:34:35 +0900
commitc1147f7f713f82d5c20dc8dfe4062f7bf671515a (patch)
tree00bd041de573ab704985cfd4ddc4b6838b08785c /ext/openssl
parentf6612203fa6ea240d83b85aa561258ece11fa48b (diff)
[ruby/openssl] ssl: avoid directly storing String object in NPN callback
On the server side, the serialized list of protocols is stored in SSL_CTX as a String object reference. We utilize a hidden instance variable to prevent it from being GC'ed, but this is not enough because it can also be relocated by GC.compact.
Diffstat (limited to 'ext/openssl')
1 files changed, 2 insertions, 2 deletions
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 9edf8b37961..d6d321e4464 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -660,7 +660,7 @@ static int
ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
void *arg)
- VALUE protocols = (VALUE)arg;
+ VALUE protocols = rb_attr_get((VALUE)arg, id_npn_protocols_encoded);
*out = (const unsigned char *) RSTRING_PTR(protocols);
*outlen = RSTRING_LENINT(protocols);
@@ -850,7 +850,7 @@ ossl_sslctx_setup(VALUE self)
if (!NIL_P(val)) {
VALUE encoded = ssl_encode_npn_protocols(val);
rb_ivar_set(self, id_npn_protocols_encoded, encoded);
- SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)encoded);
+ SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self);
OSSL_Debug("SSL NPN advertise callback added");
if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) {