Skip to content

Commit bbf7f22

Browse files
creslin2877sauwming
authored andcommitted
Locking fix so that SSL_shutdown and SSL_write are not called at same time (#3583)
1 parent 6d72311 commit bbf7f22

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

Diff for: pjlib/src/pj/ssl_sock_ossl.c

+24-4
Original file line numberDiff line numberDiff line change
@@ -1695,8 +1695,16 @@ static void ssl_destroy(pj_ssl_sock_t *ssock)
16951695
/* Reset SSL socket state */
16961696
static void ssl_reset_sock_state(pj_ssl_sock_t *ssock)
16971697
{
1698+
int post_unlock_flush_circ_buf = 0;
1699+
16981700
ossl_sock_t *ossock = (ossl_sock_t *)ssock;
16991701

1702+
/* Must lock around SSL calls, particularly SSL_shutdown
1703+
* as it can modify the write BIOs and destructively
1704+
* interfere with any ssl_write() calls in progress
1705+
* above in a multithreaded environment */
1706+
pj_lock_acquire(ssock->write_mutex);
1707+
17001708
/* Detach from SSL instance */
17011709
if (ossock->ossl_ssl) {
17021710
SSL_set_ex_data(ossock->ossl_ssl, sslsock_idx, NULL);
@@ -1710,15 +1718,21 @@ static void ssl_reset_sock_state(pj_ssl_sock_t *ssock)
17101718
if (ossock->ossl_ssl && SSL_in_init(ossock->ossl_ssl) == 0) {
17111719
int ret = SSL_shutdown(ossock->ossl_ssl);
17121720
if (ret == 0) {
1713-
/* Flush data to send close notify. */
1714-
flush_circ_buf_output(ssock, &ssock->shutdown_op_key, 0, 0);
1721+
/* SSL_shutdown will potentially trigger a bunch of
1722+
* data to dump to the socket */
1723+
post_unlock_flush_circ_buf = 1;
17151724
}
17161725
}
17171726

1718-
pj_lock_acquire(ssock->write_mutex);
17191727
ssock->ssl_state = SSL_STATE_NULL;
1728+
17201729
pj_lock_release(ssock->write_mutex);
17211730

1731+
if (post_unlock_flush_circ_buf) {
1732+
/* Flush data to send close notify. */
1733+
flush_circ_buf_output(ssock, &ssock->shutdown_op_key, 0, 0);
1734+
}
1735+
17221736
ssl_close_sockets(ssock);
17231737

17241738
/* Upon error, OpenSSL may leave any error description in the thread
@@ -2413,7 +2427,6 @@ static pj_status_t ssl_read(pj_ssl_sock_t *ssock, void *data, int *size)
24132427
*/
24142428
pj_lock_acquire(ssock->write_mutex);
24152429
*size = size_ = SSL_read(ossock->ossl_ssl, data, size_);
2416-
pj_lock_release(ssock->write_mutex);
24172430

24182431
if (size_ <= 0) {
24192432
pj_status_t status;
@@ -2436,15 +2449,22 @@ static pj_status_t ssl_read(pj_ssl_sock_t *ssock, void *data, int *size)
24362449
/* Reset SSL socket state, then return PJ_FALSE */
24372450
status = STATUS_FROM_SSL_ERR2("Read", ssock, size_,
24382451
err, len);
2452+
pj_lock_release(ssock->write_mutex);
2453+
/* Unfortunately we can't hold the lock here to reset all the state.
2454+
* We probably should though.
2455+
*/
24392456
ssl_reset_sock_state(ssock);
24402457
return status;
24412458
}
24422459
}
24432460

2461+
pj_lock_release(ssock->write_mutex);
24442462
/* Need renegotiation */
24452463
return PJ_EEOF;
24462464
}
24472465

2466+
pj_lock_release(ssock->write_mutex);
2467+
24482468
return PJ_SUCCESS;
24492469
}
24502470

0 commit comments

Comments
 (0)