aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2014-12-30 22:33:07 -0500
committerKalle Valo <kvalo@codeaurora.org>2015-01-05 03:05:44 -0500
commite9538cf4f90713eca71b1d6a74b4eae1d445c664 (patch)
treef3c3eff86b136edf1890099ffc184b61db05fd4c
parent7ce67a38f799d1fb332f672b117efbadedaa5352 (diff)
rtlwifi: Fix error when accessing unmapped memory in skb
These drivers use 9100-byte receive buffers, thus allocating an skb requires an O(3) memory allocation. Under heavy memory loads and fragmentation, such a request can fail. Previous versions of the driver have dropped the packet and reused the old buffer; however, the new version introduced a bug in that it released the old buffer before trying to allocate a new one. The previous method is implemented here. The skb is unmapped before any attempt is made to allocate another. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Cc: Stable <stable@vger.kernel.org> [v3.18] Reported-by: Eric Biggers <ebiggers3@gmail.com> Cc: Eric Biggers <ebiggers3@gmail.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 846a2e6e34d8..c70efb9a6e78 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -666,7 +666,8 @@ tx_status_ok:
666} 666}
667 667
668static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw, 668static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
669 u8 *entry, int rxring_idx, int desc_idx) 669 struct sk_buff *new_skb, u8 *entry,
670 int rxring_idx, int desc_idx)
670{ 671{
671 struct rtl_priv *rtlpriv = rtl_priv(hw); 672 struct rtl_priv *rtlpriv = rtl_priv(hw);
672 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 673 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@@ -674,11 +675,15 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
674 u8 tmp_one = 1; 675 u8 tmp_one = 1;
675 struct sk_buff *skb; 676 struct sk_buff *skb;
676 677
678 if (likely(new_skb)) {
679 skb = new_skb;
680 goto remap;
681 }
677 skb = dev_alloc_skb(rtlpci->rxbuffersize); 682 skb = dev_alloc_skb(rtlpci->rxbuffersize);
678 if (!skb) 683 if (!skb)
679 return 0; 684 return 0;
680 rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb;
681 685
686remap:
682 /* just set skb->cb to mapping addr for pci_unmap_single use */ 687 /* just set skb->cb to mapping addr for pci_unmap_single use */
683 *((dma_addr_t *)skb->cb) = 688 *((dma_addr_t *)skb->cb) =
684 pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), 689 pci_map_single(rtlpci->pdev, skb_tail_pointer(skb),
@@ -686,6 +691,7 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
686 bufferaddress = *((dma_addr_t *)skb->cb); 691 bufferaddress = *((dma_addr_t *)skb->cb);
687 if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress)) 692 if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress))
688 return 0; 693 return 0;
694 rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb;
689 if (rtlpriv->use_new_trx_flow) { 695 if (rtlpriv->use_new_trx_flow) {
690 rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false, 696 rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
691 HW_DESC_RX_PREPARE, 697 HW_DESC_RX_PREPARE,
@@ -781,6 +787,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
781 /*rx pkt */ 787 /*rx pkt */
782 struct sk_buff *skb = rtlpci->rx_ring[rxring_idx].rx_buf[ 788 struct sk_buff *skb = rtlpci->rx_ring[rxring_idx].rx_buf[
783 rtlpci->rx_ring[rxring_idx].idx]; 789 rtlpci->rx_ring[rxring_idx].idx];
790 struct sk_buff *new_skb;
784 791
785 if (rtlpriv->use_new_trx_flow) { 792 if (rtlpriv->use_new_trx_flow) {
786 rx_remained_cnt = 793 rx_remained_cnt =
@@ -807,6 +814,13 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
807 pci_unmap_single(rtlpci->pdev, *((dma_addr_t *)skb->cb), 814 pci_unmap_single(rtlpci->pdev, *((dma_addr_t *)skb->cb),
808 rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE); 815 rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE);
809 816
817 /* get a new skb - if fail, old one will be reused */
818 new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
819 if (unlikely(!new_skb)) {
820 pr_err("Allocation of new skb failed in %s\n",
821 __func__);
822 goto no_new;
823 }
810 if (rtlpriv->use_new_trx_flow) { 824 if (rtlpriv->use_new_trx_flow) {
811 buffer_desc = 825 buffer_desc =
812 &rtlpci->rx_ring[rxring_idx].buffer_desc 826 &rtlpci->rx_ring[rxring_idx].buffer_desc
@@ -911,14 +925,16 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
911 schedule_work(&rtlpriv->works.lps_change_work); 925 schedule_work(&rtlpriv->works.lps_change_work);
912 } 926 }
913end: 927end:
928 skb = new_skb;
929no_new:
914 if (rtlpriv->use_new_trx_flow) { 930 if (rtlpriv->use_new_trx_flow) {
915 _rtl_pci_init_one_rxdesc(hw, (u8 *)buffer_desc, 931 _rtl_pci_init_one_rxdesc(hw, skb, (u8 *)buffer_desc,
916 rxring_idx, 932 rxring_idx,
917 rtlpci->rx_ring[rxring_idx].idx); 933 rtlpci->rx_ring[rxring_idx].idx);
918 } else { 934 } else {
919 _rtl_pci_init_one_rxdesc(hw, (u8 *)pdesc, rxring_idx, 935 _rtl_pci_init_one_rxdesc(hw, skb, (u8 *)pdesc,
936 rxring_idx,
920 rtlpci->rx_ring[rxring_idx].idx); 937 rtlpci->rx_ring[rxring_idx].idx);
921
922 if (rtlpci->rx_ring[rxring_idx].idx == 938 if (rtlpci->rx_ring[rxring_idx].idx ==
923 rtlpci->rxringcount - 1) 939 rtlpci->rxringcount - 1)
924 rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, 940 rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc,
@@ -1307,7 +1323,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx)
1307 rtlpci->rx_ring[rxring_idx].idx = 0; 1323 rtlpci->rx_ring[rxring_idx].idx = 0;
1308 for (i = 0; i < rtlpci->rxringcount; i++) { 1324 for (i = 0; i < rtlpci->rxringcount; i++) {
1309 entry = &rtlpci->rx_ring[rxring_idx].buffer_desc[i]; 1325 entry = &rtlpci->rx_ring[rxring_idx].buffer_desc[i];
1310 if (!_rtl_pci_init_one_rxdesc(hw, (u8 *)entry, 1326 if (!_rtl_pci_init_one_rxdesc(hw, NULL, (u8 *)entry,
1311 rxring_idx, i)) 1327 rxring_idx, i))
1312 return -ENOMEM; 1328 return -ENOMEM;
1313 } 1329 }
@@ -1332,7 +1348,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx)
1332 1348
1333 for (i = 0; i < rtlpci->rxringcount; i++) { 1349 for (i = 0; i < rtlpci->rxringcount; i++) {
1334 entry = &rtlpci->rx_ring[rxring_idx].desc[i]; 1350 entry = &rtlpci->rx_ring[rxring_idx].desc[i];
1335 if (!_rtl_pci_init_one_rxdesc(hw, (u8 *)entry, 1351 if (!_rtl_pci_init_one_rxdesc(hw, NULL, (u8 *)entry,
1336 rxring_idx, i)) 1352 rxring_idx, i))
1337 return -ENOMEM; 1353 return -ENOMEM;
1338 } 1354 }