]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
chan_sip: Fix segfault during module unload 96/4496/1
authorMichael Kuron <m.kuron@gmx.de>
Sat, 26 Nov 2016 16:57:03 +0000 (17:57 +0100)
committerMichael Kuron <m.kuron@gmx.de>
Sat, 26 Nov 2016 17:20:06 +0000 (18:20 +0100)
If a TCP/TLS connection was pending (not accepted and not timed out) during
unload of chan_sip, Asterisk would segfault when trying to send a signal to
a thread whose thread ID hadn't been recorded yet. This commit fixes that by
recording the thread ID before calling the blocking connect() syscall.
This was a regression introduced by 776a14386a55b5425c7e9617eff8af8b45427144.

The above wasn't enough to fix the segfault, which was now delayed to the
point where connect() timed out. Therefore, it was necessary to also remove
the SA_RESTART flag from the SIGURG sigaction so that pthread_kill() could be
used to interruput the connect() syscall.
This was a regression introduced by 5d313f51b982a18f7321adcf7c7a4e822d8b2714.

ASTERISK-26586 #close

Change-Id: I76fd9d47d56e4264e2629bce8ec15fecba673e7b

channels/chan_sip.c
main/asterisk.c

index 870b53edf8643717a361133df45cd3f8568e822a..16d84af6c3c6b2db3364256eb259f85d1afa4ce3 100644 (file)
@@ -2957,6 +2957,7 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s
                if (!(me = sip_threadinfo_create(tcptls_session, ast_iostream_get_ssl(tcptls_session->stream) ? AST_TRANSPORT_TLS : AST_TRANSPORT_TCP))) {
                        goto cleanup;
                }
+               me->threadid = pthread_self();
                ao2_t_ref(me, +1, "Adding threadinfo ref for tcp_helper_thread");
        } else {
                struct sip_threadinfo tmp = {
@@ -2964,8 +2965,13 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s
                };
 
                if ((!(ca = tcptls_session->parent)) ||
-                       (!(me = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread"))) ||
-                       (!(tcptls_session = ast_tcptls_client_start(tcptls_session)))) {
+                       (!(me = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread")))) {
+                       goto cleanup;
+               }
+
+               me->threadid = pthread_self();
+
+               if (!(tcptls_session = ast_tcptls_client_start(tcptls_session))) {
                        goto cleanup;
                }
        }
@@ -2976,7 +2982,6 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s
                goto cleanup;
        }
 
-       me->threadid = pthread_self();
        ast_debug(2, "Starting thread for %s server\n", ast_iostream_get_ssl(tcptls_session->stream) ? "TLS" : "TCP");
 
        /* set up pollfd to watch for reads on both the socket and the alert_pipe */
index 4a6567f73eba58bb82ff88beb18d7a079e14916b..98ae8811f945a47a326b45177f5da8efc9116021 100644 (file)
@@ -1669,7 +1669,6 @@ static void _urg_handler(int num)
 
 static struct sigaction urg_handler = {
        .sa_handler = _urg_handler,
-       .sa_flags = SA_RESTART,
 };
 
 static void _hup_handler(int num)