summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2012-04-03 19:44:45 +0000
committerShaun Ruffell <sruffell@digium.com>2012-04-03 19:44:45 +0000
commit3fb4c43ebab23428e0d49087d4c703bf2cf99ae6 (patch)
tree94993aec540d4a81081fb8e5b56137f82a2adda0
parent860cbd09f898414a3345840c8f87b47e091f9319 (diff)
dahdi_dynamic_loc: Change and check the dyn->pvt pointer under lock.
Fixes a crash on unload if the sync_tick callback was running at the same time the dynamic local span was destroyed. It was possible for dahdi_dynamic_local_transmit to dereference a pointer that may have already been freed. Signed-off-by: Shaun Ruffell <sruffell@digium.com> git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10627 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r--drivers/dahdi/dahdi_dynamic_loc.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/dahdi/dahdi_dynamic_loc.c b/drivers/dahdi/dahdi_dynamic_loc.c
index 98cb7b1..4086bd8 100644
--- a/drivers/dahdi/dahdi_dynamic_loc.c
+++ b/drivers/dahdi/dahdi_dynamic_loc.c
@@ -78,10 +78,11 @@ static LIST_HEAD(dynamic_local_list);
static void
dahdi_dynamic_local_transmit(struct dahdi_dynamic *dyn, u8 *msg, size_t msglen)
{
- struct dahdi_dynamic_local *const d = dyn->pvt;
+ struct dahdi_dynamic_local *d;
unsigned long flags;
spin_lock_irqsave(&local_lock, flags);
+ d = dyn->pvt;
if (d && d->peer && d->peer->span) {
if (test_bit(DAHDI_FLAGBIT_REGISTERED, &d->peer->span->flags))
dahdi_dynamic_receive(d->peer->span, msg, msglen);
@@ -130,11 +131,12 @@ static int digit2int(char d)
static void dahdi_dynamic_local_destroy(struct dahdi_dynamic *dyn)
{
- struct dahdi_dynamic_local *d = dyn->pvt;
+ struct dahdi_dynamic_local *d;
unsigned long flags;
struct dahdi_dynamic_local *cur;
spin_lock_irqsave(&local_lock, flags);
+ d = dyn->pvt;
list_for_each_entry(cur, &dynamic_local_list, node) {
if (cur->peer == d)
cur->peer = NULL;