diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2016-12-04 21:56:06 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2016-12-05 00:32:47 +0900 |
commit | b7a15b7f3f861fe3e58c1e75299cfd154e037c5b (patch) | |
tree | eb23640452742cfa17a14c76b94495b713ea3aaa /ext/openssl | |
parent | 182604c8c35a7ae7bbf097f7d8b8d2eacc817f2c (diff) | |
download | ruby-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.
Diffstat (limited to 'ext/openssl')
-rw-r--r-- | ext/openssl/ossl_ssl.c | 5 |
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) |