mirror of https://github.com/asterisk/asterisk
ast_websocket_client_connect() takes lock_obj at the top of every pass through the retry loop. When the attempts run out it leaves through the break and returns NULL without releasing it, so the calling thread ends up holding it. The other two exits, the ast_calloc failure and the success path, do release it. The retry path also takes the lock again instead of releasing it before sleeping. The header describes lock_obj as "an ao2 object to lock while the connection is being attempted", and the usleep is the wait between attempts rather than an attempt, so that is where it should be released. chan_websocket.c passes the per-call instance as lock_obj, allocated with ao2_alloc and no flags, so it gets the default AO2_ALLOC_OPT_LOCK_MUTEX. When the object is freed, __ao2_ref() reaches ast_mutex_destroy() with the mutex still held and frees the memory anyway. There is no deadlock, Asterisk mutexes are recursive, but every call that fails to connect logs two ERROR lines. With each pass balanced, the lock is held exactly once when the loop breaks, so a single unlock before the return is enough. Fixes: #212123
parent
6df861a967
commit
fbf1311473
Loading…
Reference in new issue