freetdm: ftmod_libpri - lock the channel in libpri on_ring callback
this should fix potential call_data pointer corruption
This commit is contained in:
parent
c57c17604c
commit
ffbded67fd
|
@ -495,6 +495,7 @@ static ftdm_state_map_t isdn_state_map = {
|
||||||
/**
|
/**
|
||||||
* \brief Handler for channel state change
|
* \brief Handler for channel state change
|
||||||
* \param ftdmchan Channel to handle
|
* \param ftdmchan Channel to handle
|
||||||
|
* \note This function MUST be called with the channel locked
|
||||||
*/
|
*/
|
||||||
static __inline__ void state_advance(ftdm_channel_t *chan)
|
static __inline__ void state_advance(ftdm_channel_t *chan)
|
||||||
{
|
{
|
||||||
|
@ -989,7 +990,16 @@ static int on_ring(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event
|
||||||
|
|
||||||
if (!chan) {
|
if (!chan) {
|
||||||
ftdm_log(FTDM_LOG_ERROR, "-- Unable to get channel %d:%d\n", ftdm_span_get_id(span), pevent->ring.channel);
|
ftdm_log(FTDM_LOG_ERROR, "-- Unable to get channel %d:%d\n", ftdm_span_get_id(span), pevent->ring.channel);
|
||||||
goto done;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ftdm_channel_lock(chan);
|
||||||
|
|
||||||
|
if (chan->call_data) {
|
||||||
|
/* we could drop the incoming call, but most likely the pointer is just a ghost of the past,
|
||||||
|
* this check is just to detect potentially unreleased pointers */
|
||||||
|
ftdm_log_chan(chan, FTDM_LOG_ERROR, "channel already has call %p!\n", chan->call_data);
|
||||||
|
chan->call_data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ftdm_channel_get_state(chan) != FTDM_CHANNEL_STATE_DOWN || ftdm_test_flag(chan, FTDM_CHANNEL_INUSE)) {
|
if (ftdm_channel_get_state(chan) != FTDM_CHANNEL_STATE_DOWN || ftdm_test_flag(chan, FTDM_CHANNEL_INUSE)) {
|
||||||
|
@ -1049,9 +1059,10 @@ static int on_ring(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event
|
||||||
/* hurr, this is valid as along as nobody releases the call */
|
/* hurr, this is valid as along as nobody releases the call */
|
||||||
chan->call_data = pevent->ring.call;
|
chan->call_data = pevent->ring.call;
|
||||||
|
|
||||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RING);
|
ftdm_set_state(chan, FTDM_CHANNEL_STATE_RING);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
ftdm_channel_unlock(chan);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue