From da52933550fd4736aa1c213b6de497e2ffc31e34 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 13 Nov 2015 16:00:39 +0300 Subject: [PATCH] be_openssl: don't call do_write() directly from outbuf_cb Otherwise we can trigger incorrect callback, the simplest way to trigger this is using http regression tests -- https_chunk_out, since all it do is: evhttp_send_reply_end() evbuffer_add() do_write() evhttp_write_buffer() evcon->cb = cb And indeed this is what happens: (gdb) bt #0 do_write (bev_ssl=0x738a90, atmost=16384) at bufferevent_openssl.c:717 #1 0x00000000004b69f7 in consider_writing (bev_ssl=0x738a90) at bufferevent_openssl.c:875 #2 0x00000000004b7386 in be_openssl_outbuf_cb (buf=0x7387b0, cbinfo=0x7fffffffd590, arg=0x738a90) at bufferevent_openssl.c:1147 #3 0x0000000000490100 in evbuffer_run_callbacks (buffer=0x7387b0, running_deferred=0) at buffer.c:508 #4 0x00000000004901e5 in evbuffer_invoke_callbacks_ (buffer=0x7387b0) at buffer.c:529 #5 0x0000000000493a30 in evbuffer_add (buf=0x7387b0, data_in=0x4ecfb2, datlen=5) at buffer.c:1803 #6 0x00000000004be2e3 in evhttp_send_reply_end (req=0x7371a0) at http.c:2794 #7 0x000000000045c407 in http_chunked_trickle_cb (fd=-1, events=1, arg=0x75aaf0) at regress_http.c:402 ... (gdb) p bev.writecb $4 = (bufferevent_data_cb) 0x4ba17e $5 = (void *) 0x7379b0 (gdb) p (struct evhttp_connection *)bev.cbarg $6 = (struct evhttp_connection *) 0x7379b0 (gdb) p $6->cb $7 = (void (*)(struct evhttp_connection *, void *)) 0x0 And be_sock don't do like this anyway. Fixes: https_chunk_out --- bufferevent_openssl.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c index 7e4d1744..37478b6a 100644 --- a/bufferevent_openssl.c +++ b/bufferevent_openssl.c @@ -1139,14 +1139,13 @@ be_openssl_outbuf_cb(struct evbuffer *buf, int r = 0; /* XXX need to hold a reference here. */ - if (cbinfo->n_added && bev_ssl->state == BUFFEREVENT_SSL_OPEN) { - if (cbinfo->orig_size == 0) - r = bufferevent_add_event_(&bev_ssl->bev.bev.ev_write, - &bev_ssl->bev.bev.timeout_write); - consider_writing(bev_ssl); + if (cbinfo->n_added && bev_ssl->state == BUFFEREVENT_SSL_OPEN && + cbinfo->orig_size == 0) { + r = bufferevent_add_event_(&bev_ssl->bev.bev.ev_write, + &bev_ssl->bev.bev.timeout_write); } /* XXX Handle r < 0 */ - (void)r; + (void)r; } -- 2.40.0