dahdi: dahdi_chan.ec_factory can be protected with the mutex.
This is never accessed or modified in interrupt context. This closes a potential race if the echocan is being changed on a channel while enabling disabling is hapening on another thread. Signed-off-by: Shaun Ruffell <sruffell@digium.com> Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
This commit is contained in:
parent
761e02da52
commit
a3578ca156
@ -991,10 +991,13 @@ static int dahdi_seq_show(struct seq_file *sfile, void *data)
|
|||||||
|
|
||||||
seq_fill_alarm_string(sfile, chan->chan_alarms);
|
seq_fill_alarm_string(sfile, chan->chan_alarms);
|
||||||
|
|
||||||
if (chan->ec_factory)
|
mutex_lock(&chan->mutex);
|
||||||
|
if (chan->ec_factory) {
|
||||||
seq_printf(sfile, "(EC: %s - %s) ",
|
seq_printf(sfile, "(EC: %s - %s) ",
|
||||||
chan->ec_factory->get_name(chan),
|
chan->ec_factory->get_name(chan),
|
||||||
chan->ec_state ? "ACTIVE" : "INACTIVE");
|
chan->ec_state ? "ACTIVE" : "INACTIVE");
|
||||||
|
}
|
||||||
|
mutex_unlock(&chan->mutex);
|
||||||
|
|
||||||
seq_printf(sfile, "\n");
|
seq_printf(sfile, "\n");
|
||||||
}
|
}
|
||||||
@ -1489,14 +1492,13 @@ static const struct dahdi_echocan_factory hwec_factory = {
|
|||||||
static int dahdi_enable_hw_preechocan(struct dahdi_chan *chan)
|
static int dahdi_enable_hw_preechocan(struct dahdi_chan *chan)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&chan->lock, flags);
|
mutex_lock(&chan->mutex);
|
||||||
if (chan->ec_factory != &hwec_factory)
|
if (chan->ec_factory != &hwec_factory)
|
||||||
res = -ENODEV;
|
res = -ENODEV;
|
||||||
else
|
else
|
||||||
res = 0;
|
res = 0;
|
||||||
spin_unlock_irqrestore(&chan->lock, flags);
|
mutex_unlock(&chan->mutex);
|
||||||
|
|
||||||
if (-ENODEV == res)
|
if (-ENODEV == res)
|
||||||
return 0;
|
return 0;
|
||||||
@ -2303,10 +2305,10 @@ static void dahdi_chan_unreg(struct dahdi_chan *chan)
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&chan->lock, flags);
|
mutex_lock(&chan->mutex);
|
||||||
release_echocan(chan->ec_factory);
|
release_echocan(chan->ec_factory);
|
||||||
chan->ec_factory = NULL;
|
chan->ec_factory = NULL;
|
||||||
spin_unlock_irqrestore(&chan->lock, flags);
|
mutex_unlock(&chan->mutex);
|
||||||
|
|
||||||
#ifdef CONFIG_DAHDI_NET
|
#ifdef CONFIG_DAHDI_NET
|
||||||
if (dahdi_have_netdev(chan)) {
|
if (dahdi_have_netdev(chan)) {
|
||||||
@ -5227,7 +5229,6 @@ static bool dahdi_is_hwec_available(const struct dahdi_chan *chan)
|
|||||||
|
|
||||||
static int dahdi_ioctl_attach_echocan(unsigned long data)
|
static int dahdi_ioctl_attach_echocan(unsigned long data)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct dahdi_chan *chan;
|
struct dahdi_chan *chan;
|
||||||
struct dahdi_attach_echocan ae;
|
struct dahdi_attach_echocan ae;
|
||||||
const struct dahdi_echocan_factory *new = NULL, *old;
|
const struct dahdi_echocan_factory *new = NULL, *old;
|
||||||
@ -5269,10 +5270,10 @@ static int dahdi_ioctl_attach_echocan(unsigned long data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&chan->lock, flags);
|
mutex_lock(&chan->mutex);
|
||||||
old = chan->ec_factory;
|
old = chan->ec_factory;
|
||||||
chan->ec_factory = new;
|
chan->ec_factory = new;
|
||||||
spin_unlock_irqrestore(&chan->lock, flags);
|
mutex_unlock(&chan->mutex);
|
||||||
|
|
||||||
if (old)
|
if (old)
|
||||||
release_echocan(old);
|
release_echocan(old);
|
||||||
|
Loading…
Reference in New Issue
Block a user