Skip to content

Commit bca463e

Browse files
Chin-Ran Lolinvjw
authored andcommitted
mwifiex: fix tx_info/rx_info overlap with PCIe dma_mapping
On PCIe Tx data path, network interface specific tx_info parameters such as bss_num and bss_type are saved at "skb->cb + sizeof(dma_addr_t)" (returned by MWIFIEX_SKB_TXCB). Later mwifiex_map_pci_memory() called from mwifiex_pcie_send_data() will memcpy sizeof(struct mwifiex_dma_mapping) bytes to save PCIe DMA address and length information at beginning of skb->cb. This accidently overwrites bss_num and bss_type saved in skb->cb previously because bss_num/bss_type and mwifiex_dma_mapping data overlap. Similarly, on PCIe Rx data path, rx_info parameters overlaps with PCIe DMA address and length information too. Fix it by defining mwifiex_cb structure and having MWIFIEX_SKB_TXCB and MWIFIEX_SKB_RXCB return the correct address of tx_info/rx_info using the structure members. Also add a BUILD_BUG_ON to maks sure that mwifiex_cb structure doesn't exceed the size of skb->cb. Reviewed-by: Aaron Durbin <adurbin@chromium.org> Signed-off-by: Chin-Ran Lo <crlo@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
1 parent f15ec34 commit bca463e

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

drivers/net/wireless/mwifiex/pcie.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
5050
return -1;
5151
}
5252
mapping.len = size;
53-
memcpy(skb->cb, &mapping, sizeof(mapping));
53+
mwifiex_store_mapping(skb, &mapping);
5454
return 0;
5555
}
5656

@@ -60,7 +60,7 @@ static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter,
6060
struct pcie_service_card *card = adapter->card;
6161
struct mwifiex_dma_mapping mapping;
6262

63-
MWIFIEX_SKB_PACB(skb, &mapping);
63+
mwifiex_get_mapping(skb, &mapping);
6464
pci_unmap_single(card->dev, mapping.addr, mapping.len, flags);
6565
}
6666

drivers/net/wireless/mwifiex/util.h

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,55 @@
2020
#ifndef _MWIFIEX_UTIL_H_
2121
#define _MWIFIEX_UTIL_H_
2222

23+
struct mwifiex_dma_mapping {
24+
dma_addr_t addr;
25+
size_t len;
26+
};
27+
28+
struct mwifiex_cb {
29+
struct mwifiex_dma_mapping dma_mapping;
30+
union {
31+
struct mwifiex_rxinfo rx_info;
32+
struct mwifiex_txinfo tx_info;
33+
};
34+
};
35+
2336
static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb)
2437
{
25-
return (struct mwifiex_rxinfo *)(skb->cb + sizeof(dma_addr_t));
38+
struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
39+
40+
BUILD_BUG_ON(sizeof(struct mwifiex_cb) > sizeof(skb->cb));
41+
return &cb->rx_info;
2642
}
2743

2844
static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb)
2945
{
30-
return (struct mwifiex_txinfo *)(skb->cb + sizeof(dma_addr_t));
46+
struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
47+
48+
return &cb->tx_info;
3149
}
3250

33-
struct mwifiex_dma_mapping {
34-
dma_addr_t addr;
35-
size_t len;
36-
};
51+
static inline void mwifiex_store_mapping(struct sk_buff *skb,
52+
struct mwifiex_dma_mapping *mapping)
53+
{
54+
struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
55+
56+
memcpy(&cb->dma_mapping, mapping, sizeof(*mapping));
57+
}
3758

38-
static inline void MWIFIEX_SKB_PACB(struct sk_buff *skb,
39-
struct mwifiex_dma_mapping *mapping)
59+
static inline void mwifiex_get_mapping(struct sk_buff *skb,
60+
struct mwifiex_dma_mapping *mapping)
4061
{
41-
memcpy(mapping, skb->cb, sizeof(*mapping));
62+
struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
63+
64+
memcpy(mapping, &cb->dma_mapping, sizeof(*mapping));
4265
}
4366

4467
static inline dma_addr_t MWIFIEX_SKB_DMA_ADDR(struct sk_buff *skb)
4568
{
4669
struct mwifiex_dma_mapping mapping;
4770

48-
MWIFIEX_SKB_PACB(skb, &mapping);
71+
mwifiex_get_mapping(skb, &mapping);
4972

5073
return mapping.addr;
5174
}

0 commit comments

Comments
 (0)