mISDN: fix use-after-free bugs in l1oip timer handlers
[linux-2.6-microblaze.git] / drivers / isdn / mISDN / l1oip_core.c
index 2c40412..a77195e 100644 (file)
@@ -275,7 +275,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
        p = frame;
 
        /* restart timer */
-       if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ))
+       if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ) && !hc->shutdown)
                mod_timer(&hc->keep_tl, jiffies + L1OIP_KEEPALIVE * HZ);
        else
                hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ;
@@ -601,7 +601,9 @@ multiframe:
                goto multiframe;
 
        /* restart timer */
-       if (time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) || !hc->timeout_on) {
+       if ((time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) ||
+            !hc->timeout_on) &&
+           !hc->shutdown) {
                hc->timeout_on = 1;
                mod_timer(&hc->timeout_tl, jiffies + L1OIP_TIMEOUT * HZ);
        } else /* only adjust timer */
@@ -1232,11 +1234,10 @@ release_card(struct l1oip *hc)
 {
        int     ch;
 
-       if (timer_pending(&hc->keep_tl))
-               del_timer(&hc->keep_tl);
+       hc->shutdown = true;
 
-       if (timer_pending(&hc->timeout_tl))
-               del_timer(&hc->timeout_tl);
+       del_timer_sync(&hc->keep_tl);
+       del_timer_sync(&hc->timeout_tl);
 
        cancel_work_sync(&hc->workq);