diff options
author | Shaun Ruffell <sruffell@digium.com> | 2012-04-03 20:10:20 +0000 |
---|---|---|
committer | Shaun Ruffell <sruffell@digium.com> | 2012-04-03 20:10:20 +0000 |
commit | a1f0bc9a642394fd4e0667141392350151e962fd (patch) | |
tree | be80dc8574a312b234dde7f04a7c2f2f30e5965f | |
parent | c40a35924b218bf1f57f1e01fc79ed90d78279a7 (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>
Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10627
git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10632 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r-- | drivers/dahdi/dahdi_dynamic_loc.c | 6 |
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; |