1 From 9e67e0d5c3fdc747530a956038b374fca4748b76 Mon Sep 17 00:00:00 2001
2 From: riza <riza@localhost>
3 Date: Thu, 13 Oct 2016 09:02:50 +0000
4 Subject: [PATCH 1/4] Re #1969: Fix crash on using an already destroyed SSL
8 pjlib/src/pj/ssl_sock_ossl.c | 66 ++++++++++++++++++++++++++++----------------
9 1 file changed, 42 insertions(+), 24 deletions(-)
11 diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
12 index fa0db2d..ceab67a 100644
13 --- a/pjlib/src/pj/ssl_sock_ossl.c
14 +++ b/pjlib/src/pj/ssl_sock_ossl.c
15 @@ -822,7 +822,10 @@ static void close_sockets(pj_ssl_sock_t *ssock)
16 pj_lock_acquire(ssock->write_mutex);
19 - ssock->asock = NULL;
20 + // Don't set ssock->asock to NULL, as it may trigger assertion in
21 + // send operation. This should be safe as active socket will simply
22 + // return PJ_EINVALIDOP on any operation if it is already closed.
23 + //ssock->asock = NULL;
24 ssock->sock = PJ_INVALID_SOCKET;
27 @@ -841,9 +844,9 @@ static void close_sockets(pj_ssl_sock_t *ssock)
28 /* Reset SSL socket state */
29 static void reset_ssl_sock_state(pj_ssl_sock_t *ssock)
31 + pj_lock_acquire(ssock->write_mutex);
32 ssock->ssl_state = SSL_STATE_NULL;
35 + pj_lock_release(ssock->write_mutex);
39 @@ -1612,6 +1615,21 @@ static pj_status_t do_handshake(pj_ssl_sock_t *ssock)
43 +static void ssl_on_destroy(void *arg)
45 + pj_pool_t *pool = NULL;
46 + pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)arg;
50 + pj_lock_destroy(ssock->write_mutex);
55 + pj_pool_release(pool);
60 *******************************************************************
61 @@ -1830,7 +1848,7 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
63 /* Create new SSL socket instance */
64 status = pj_ssl_sock_create(ssock_parent->pool,
65 - &ssock_parent->newsock_param, &ssock);
66 + &ssock_parent->newsock_param, &ssock);
67 if (status != PJ_SUCCESS)
70 @@ -1906,12 +1924,10 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
71 if (status != PJ_SUCCESS)
74 - /* Temporarily add ref the group lock until active socket creation,
75 - * to make sure that group lock is destroyed if the active socket
78 pj_grp_lock_add_ref(glock);
79 asock_cfg.grp_lock = ssock->param.grp_lock = glock;
80 + pj_grp_lock_add_handler(ssock->param.grp_lock, ssock->pool, ssock,
84 pj_bzero(&asock_cb, sizeof(asock_cb));
85 @@ -1927,11 +1943,6 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
89 - /* This will destroy the group lock if active socket creation fails */
90 - if (asock_cfg.grp_lock) {
91 - pj_grp_lock_dec_ref(asock_cfg.grp_lock);
94 if (status != PJ_SUCCESS)
97 @@ -2251,17 +2262,26 @@ PJ_DEF(pj_status_t) pj_ssl_sock_create (pj_pool_t *pool,
98 /* Create secure socket mutex */
99 status = pj_lock_create_recursive_mutex(pool, pool->obj_name,
100 &ssock->write_mutex);
101 - if (status != PJ_SUCCESS)
102 + if (status != PJ_SUCCESS) {
103 + pj_pool_release(pool);
107 /* Init secure socket param */
108 pj_ssl_sock_param_copy(pool, &ssock->param, param);
110 + if (ssock->param.grp_lock) {
111 + pj_grp_lock_add_ref(ssock->param.grp_lock);
112 + pj_grp_lock_add_handler(ssock->param.grp_lock, pool, ssock,
116 ssock->param.read_buffer_size = ((ssock->param.read_buffer_size+7)>>3)<<3;
117 if (!ssock->param.timer_heap) {
118 PJ_LOG(3,(ssock->pool->obj_name, "Warning: timer heap is not "
119 "available. It is recommended to supply one to avoid "
120 - "a race condition if more than one worker threads "
122 + "a race condition if more than one worker threads "
127 @@ -2277,8 +2297,6 @@ PJ_DEF(pj_status_t) pj_ssl_sock_create (pj_pool_t *pool,
129 PJ_DEF(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock)
133 PJ_ASSERT_RETURN(ssock, PJ_EINVAL);
136 @@ -2290,12 +2308,11 @@ PJ_DEF(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock)
139 reset_ssl_sock_state(ssock);
140 - pj_lock_destroy(ssock->write_mutex);
142 - pool = ssock->pool;
143 - ssock->pool = NULL;
145 - pj_pool_release(pool);
146 + if (ssock->param.grp_lock) {
147 + pj_grp_lock_dec_ref(ssock->param.grp_lock);
149 + ssl_on_destroy(ssock);
154 @@ -2782,6 +2799,7 @@ pj_ssl_sock_start_accept2(pj_ssl_sock_t *ssock,
156 /* Start accepting */
157 pj_ssl_sock_param_copy(pool, &ssock->newsock_param, newsock_param);
158 + ssock->newsock_param.grp_lock = NULL;
159 status = pj_activesock_start_accept(ssock->asock, pool);
160 if (status != PJ_SUCCESS)