iwl3945: fix possible il->txq NULL pointer dereference in delayed works
authorStanislaw Gruszka <sgruszka@redhat.com>
Thu, 8 Mar 2012 12:16:01 +0000 (13:16 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 12 Mar 2012 18:00:16 +0000 (14:00 -0400)
On il3945_down procedure we free tx queue data and nullify il->txq
pointer. After that we drop mutex and then cancel delayed works. There
is possibility, that after drooping mutex and before the cancel, some
delayed work will start and crash while trying to send commands to
the device. For example, here is reported crash in
il3945_bg_reg_txpower_periodic():
https://bugzilla.kernel.org/show_bug.cgi?id=42766#c10

Patch fix problem by adding il->txq check on works that send commands,
hence utilize tx queue.

Reported-by: Clemens Eisserer <linuxhippy@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/iwlegacy/3945-mac.c
drivers/net/wireless/iwlegacy/3945.c

index 54b2d391e91a942bbbbbe08e5ff65347a22328ac..a7dfba8d164efb1eea0cc06b4de049220281e168 100644 (file)
@@ -2475,7 +2475,7 @@ il3945_bg_alive_start(struct work_struct *data)
            container_of(data, struct il_priv, alive_start.work);
 
        mutex_lock(&il->mutex);
-       if (test_bit(S_EXIT_PENDING, &il->status))
+       if (test_bit(S_EXIT_PENDING, &il->status) || il->txq == NULL)
                goto out;
 
        il3945_alive_start(il);
index 1489b1573a6a3d62384a0e1b9f7fdbb490d71126..c80eb9b315517621f41aa90b58ba8c4c6b8a896c 100644 (file)
@@ -1870,11 +1870,12 @@ il3945_bg_reg_txpower_periodic(struct work_struct *work)
        struct il_priv *il = container_of(work, struct il_priv,
                                          _3945.thermal_periodic.work);
 
-       if (test_bit(S_EXIT_PENDING, &il->status))
-               return;
-
        mutex_lock(&il->mutex);
+       if (test_bit(S_EXIT_PENDING, &il->status) || il->txq == NULL)
+               goto out;
+
        il3945_reg_txpower_periodic(il);
+out:
        mutex_unlock(&il->mutex);
 }