summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn.c
diff options
context:
space:
mode:
authorZhu Yi2009-10-23 22:42:25 +0200
committerJohn W. Linville2009-10-27 21:50:01 +0100
commit29b1b2688fd71346f78f175d9669c006686b6dc3 (patch)
tree8d7a337761cc88dae60f4d5e44eb5fd9fbe53858 /drivers/net/wireless/iwlwifi/iwl-agn.c
parentiwlwifi: specify the valid tx/rx chain in device config structure (diff)
downloadkernel-qcow2-linux-29b1b2688fd71346f78f175d9669c006686b6dc3.tar.gz
kernel-qcow2-linux-29b1b2688fd71346f78f175d9669c006686b6dc3.tar.xz
kernel-qcow2-linux-29b1b2688fd71346f78f175d9669c006686b6dc3.zip
iwlwifi: fix use after free bug for paged rx
In the paged rx patch (4854fde2), I introduced a bug that could possibly touch an already freed page. It is fixed by avoiding the access in this patch. I've also added some comments so that other people touching the code won't make the same mistake. In the future, if we cannot avoid access the page after being handled to the upper layer, we can use get_page/put_page to handle it. For now, it's just not necessary. It also fixed a debug message print bug reported by Stanislaw Gruszka <sgruszka@redhat.com>. Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index a34acb7e44c3..0d3886505205 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -814,8 +814,8 @@ void iwl_rx_handle(struct iwl_priv *priv)
if (priv->rx_handlers[pkt->hdr.cmd]) {
IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r,
i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
- priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
+ priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
} else {
/* No handling needed */
IWL_DEBUG_RX(priv,
@@ -824,11 +824,18 @@ void iwl_rx_handle(struct iwl_priv *priv)
pkt->hdr.cmd);
}
+ /*
+ * XXX: After here, we should always check rxb->page
+ * against NULL before touching it or its virtual
+ * memory (pkt). Because some rx_handler might have
+ * already taken or freed the pages.
+ */
+
if (reclaim) {
/* Invoke any callbacks, transfer the buffer to caller,
* and fire off the (possibly) blocking iwl_send_cmd()
* as we reclaim the driver command queue */
- if (rxb && rxb->page)
+ if (rxb->page)
iwl_tx_cmd_complete(priv, rxb);
else
IWL_WARN(priv, "Claim null rxb?\n");