aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2016-12-04 21:56:06 +0900
committerKazuki Yamaguchi <k@rhe.jp>2016-12-05 00:32:47 +0900
commitb7a15b7f3f861fe3e58c1e75299cfd154e037c5b (patch)
treeeb23640452742cfa17a14c76b94495b713ea3aaa
parent182604c8c35a7ae7bbf097f7d8b8d2eacc817f2c (diff)
downloadruby-openssl-b7a15b7f3f861fe3e58c1e75299cfd154e037c5b.tar.gz
ssl: prevent encoded NPN advertised protocol list from being GCed
SSLContext#setup encodes the protocol list set in @npn_protocols into a String. The String is passed to SSL_CTX_set_next_protos_advertised_cb() and OpenSSL invokes the callback function with the String. However since Ruby's GC can't find the reference to the String from the inside of OpenSSL, it can be free'd before the callback is invoked. So store the String in an instance variable to prevent this.
-rw-r--r--ext/openssl/ossl_ssl.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 609ffdc6..eef7dbec 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -32,7 +32,8 @@ VALUE cSSLSocket;
static VALUE eSSLErrorWaitReadable;
static VALUE eSSLErrorWaitWritable;
-static ID ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback;
+static ID ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback,
+ id_npn_protocols_encoded;
static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
@@ -892,6 +893,7 @@ ossl_sslctx_setup(VALUE self)
val = rb_attr_get(self, id_i_npn_protocols);
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);
OSSL_Debug("SSL NPN advertise callback added");
}
@@ -2712,6 +2714,7 @@ Init_ossl_ssl(void)
id_tmp_dh_callback = rb_intern("tmp_dh_callback");
id_tmp_ecdh_callback = rb_intern("tmp_ecdh_callback");
+ id_npn_protocols_encoded = rb_intern("npn_protocols_encoded");
#define DefIVarID(name) do \
id_i_##name = rb_intern("@"#name); while (0)