[asterisk-bugs] [JIRA] (ASTERISK-29217) LOCK() can grant the same lock to multiple channels spuriously

Joshua C. Colp (JIRA) noreply at issues.asterisk.org
Mon Dec 21 06:35:17 CST 2020


     [ https://issues.asterisk.org/jira/browse/ASTERISK-29217?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Work on ASTERISK-29217 started by Jaco Kroon.

> LOCK() can grant the same lock to multiple channels spuriously
> --------------------------------------------------------------
>
>                 Key: ASTERISK-29217
>                 URL: https://issues.asterisk.org/jira/browse/ASTERISK-29217
>             Project: Asterisk
>          Issue Type: Bug
>      Security Level: None
>          Components: Functions/func_lock
>    Affects Versions: 13.38.0, 16.15.0, 17.9.0, 18.1.0
>            Reporter: Jaco Kroon
>            Assignee: Jaco Kroon
>
> Due to a misunderstanding of the wait conditions work in the func/func_lock.c code it's possible that multiple channels will be informed of a successful LOCK(), resulting in bad stuff happening.
> Under low lock pressure scenarios this is unlikely to happen (ie, no more than 1 channel should be blocking on LOCK()), but the moment multiple channels are waiting it becomes (but is not guaranteed) possible for multiple channels to be informed they've successfully locked.
> Technical details:
> From PTHREAD_COND_BROADCAST(3P):
>        On a multi-processor, it may be impossible for an implementation of  pthread_cond_signal()
>        to avoid the unblocking of more than one thread blocked on a condition variable. For exam‐
>        ple,  consider  the  following   partial   implementation   of   pthread_cond_wait()   and
>        pthread_cond_signal(), executed by two threads in the order given. One thread is trying to
>        wait on the condition variable, another is concurrently  executing  pthread_cond_signal(),
>        while a third thread is already waiting.
> I won't bore you with the sample code, but what this says is that multiple threads may be woken.  func_lock assumes that it's the only one and assumes it owns the lock on successful return from ast_cond_timedwait (which wraps the pthread_cond_timedwait).
> So let's say two threads gets released here.
> At this point the threads will sequentially be released (since the mutex gets grabbed again).
> The first thread will set ->owner to itself, and increment ->count to 1.
> The second thread will set ->owner to itself, and increment ->count to 2.
> When the first thread calls UNLOCK() it will be informed it doens't own the lock.
> When the second thread calls UNLOCK() it will decrement ->count to 1, and not release the lock until the channel is destroyed.
> The lock_broker thread probably further aggravates the problems here, so my patch will elimate it's use as well.



--
This message was sent by Atlassian JIRA
(v6.2#6252)



More information about the asterisk-bugs mailing list