[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