Skip to content

Commit 3a2bf74

Browse files
committed
ssl: fix potential exception in servername_cb
ssl_servername_cb() is a callback function called from OpenSSL and Ruby exceptions must not be raised from it. Allocate the Array within rb_protect().
1 parent 0759018 commit 3a2bf74

File tree

1 file changed

+16
-26
lines changed

1 file changed

+16
-26
lines changed

ext/openssl/ossl_ssl.c

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -557,52 +557,42 @@ ossl_sslctx_add_extra_chain_cert_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg))
557557
static VALUE ossl_sslctx_setup(VALUE self);
558558

559559
static VALUE
560-
ossl_call_servername_cb(VALUE ary)
560+
ossl_call_servername_cb(VALUE arg)
561561
{
562-
VALUE ssl_obj, sslctx_obj, cb, ret_obj;
563-
564-
Check_Type(ary, T_ARRAY);
565-
ssl_obj = rb_ary_entry(ary, 0);
562+
SSL *ssl = (void *)arg;
563+
const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
564+
if (!servername)
565+
return Qnil;
566566

567-
sslctx_obj = rb_attr_get(ssl_obj, id_i_context);
568-
cb = rb_attr_get(sslctx_obj, id_i_servername_cb);
569-
if (NIL_P(cb)) return Qnil;
567+
VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
568+
VALUE sslctx_obj = rb_attr_get(ssl_obj, id_i_context);
569+
VALUE cb = rb_attr_get(sslctx_obj, id_i_servername_cb);
570+
VALUE ary = rb_assoc_new(ssl_obj, rb_str_new_cstr(servername));
570571

571-
ret_obj = rb_funcallv(cb, id_call, 1, &ary);
572+
VALUE ret_obj = rb_funcallv(cb, id_call, 1, &ary);
572573
if (rb_obj_is_kind_of(ret_obj, cSSLContext)) {
573-
SSL *ssl;
574574
SSL_CTX *ctx2;
575-
576575
ossl_sslctx_setup(ret_obj);
577-
GetSSL(ssl_obj, ssl);
578576
GetSSLCTX(ret_obj, ctx2);
579-
SSL_set_SSL_CTX(ssl, ctx2);
577+
if (!SSL_set_SSL_CTX(ssl, ctx2))
578+
ossl_raise(eSSLError, "SSL_set_SSL_CTX");
580579
rb_ivar_set(ssl_obj, id_i_context, ret_obj);
581580
} else if (!NIL_P(ret_obj)) {
582581
ossl_raise(rb_eArgError, "servername_cb must return an "
583582
"OpenSSL::SSL::SSLContext object or nil");
584583
}
585584

586-
return ret_obj;
585+
return Qnil;
587586
}
588587

589588
static int
590589
ssl_servername_cb(SSL *ssl, int *ad, void *arg)
591590
{
592-
VALUE ary, ssl_obj;
593-
int state = 0;
594-
const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
595-
596-
if (!servername)
597-
return SSL_TLSEXT_ERR_OK;
598-
599-
ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
600-
ary = rb_ary_new2(2);
601-
rb_ary_push(ary, ssl_obj);
602-
rb_ary_push(ary, rb_str_new2(servername));
591+
int state;
603592

604-
rb_protect(ossl_call_servername_cb, ary, &state);
593+
rb_protect(ossl_call_servername_cb, (VALUE)ssl, &state);
605594
if (state) {
595+
VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
606596
rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
607597
return SSL_TLSEXT_ERR_ALERT_FATAL;
608598
}

0 commit comments

Comments
 (0)