diff options
author | Zhu Yi <yi.zhu@intel.com> | 2009-10-23 16:42:25 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-10-27 16:50:01 -0400 |
commit | 29b1b2688fd71346f78f175d9669c006686b6dc3 (patch) | |
tree | 8d7a337761cc88dae60f4d5e44eb5fd9fbe53858 /drivers/net/wireless/iwlwifi/iwl-agn.c | |
parent | 52aa081c40324ecb04a47864e4e56dafc5a72a34 (diff) |
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.c | 11 |
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) | |||
814 | if (priv->rx_handlers[pkt->hdr.cmd]) { | 814 | if (priv->rx_handlers[pkt->hdr.cmd]) { |
815 | IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, | 815 | IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, |
816 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | 816 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); |
817 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | ||
818 | priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; | 817 | priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; |
818 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | ||
819 | } else { | 819 | } else { |
820 | /* No handling needed */ | 820 | /* No handling needed */ |
821 | IWL_DEBUG_RX(priv, | 821 | IWL_DEBUG_RX(priv, |
@@ -824,11 +824,18 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
824 | pkt->hdr.cmd); | 824 | pkt->hdr.cmd); |
825 | } | 825 | } |
826 | 826 | ||
827 | /* | ||
828 | * XXX: After here, we should always check rxb->page | ||
829 | * against NULL before touching it or its virtual | ||
830 | * memory (pkt). Because some rx_handler might have | ||
831 | * already taken or freed the pages. | ||
832 | */ | ||
833 | |||
827 | if (reclaim) { | 834 | if (reclaim) { |
828 | /* Invoke any callbacks, transfer the buffer to caller, | 835 | /* Invoke any callbacks, transfer the buffer to caller, |
829 | * and fire off the (possibly) blocking iwl_send_cmd() | 836 | * and fire off the (possibly) blocking iwl_send_cmd() |
830 | * as we reclaim the driver command queue */ | 837 | * as we reclaim the driver command queue */ |
831 | if (rxb && rxb->page) | 838 | if (rxb->page) |
832 | iwl_tx_cmd_complete(priv, rxb); | 839 | iwl_tx_cmd_complete(priv, rxb); |
833 | else | 840 | else |
834 | IWL_WARN(priv, "Claim null rxb?\n"); | 841 | IWL_WARN(priv, "Claim null rxb?\n"); |