Commit 5aa9f0ea authored by Arend van Spriel's avatar Arend van Spriel Committed by John W. Linville

brcmfmac: fix use of skb control buffer in SDIO driver part

The SDIO driver has a 16-bit field defined in the skbuff control buffer.
However, it is accessed as a u32 overwriting other control info. Another
issue is that the field is not initialized for networking packets, but
the control buffer content is unspecified as other networking layers can
use it.
Reviewed-by: default avatarHante Meuleman <meuleman@broadcom.com>
Reviewed-by: default avatarFranky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: default avatarDaniel (Deognyoun) Kim <dekim@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 68ca395f
...@@ -2112,7 +2112,7 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus, ...@@ -2112,7 +2112,7 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus,
memcpy(pkt_pad->data, memcpy(pkt_pad->data,
pkt->data + pkt->len - tail_chop, pkt->data + pkt->len - tail_chop,
tail_chop); tail_chop);
*(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop; *(u16 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop;
skb_trim(pkt, pkt->len - tail_chop); skb_trim(pkt, pkt->len - tail_chop);
__skb_queue_after(pktq, pkt, pkt_pad); __skb_queue_after(pktq, pkt, pkt_pad);
} else { } else {
...@@ -2159,7 +2159,7 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq, ...@@ -2159,7 +2159,7 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
* already properly aligned and does not * already properly aligned and does not
* need an sdpcm header. * need an sdpcm header.
*/ */
if (*(u32 *)(pkt_next->cb) & ALIGN_SKB_FLAG) if (*(u16 *)(pkt_next->cb) & ALIGN_SKB_FLAG)
continue; continue;
/* align packet data pointer */ /* align packet data pointer */
...@@ -2223,11 +2223,11 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq) ...@@ -2223,11 +2223,11 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq)
u8 *hdr; u8 *hdr;
u32 dat_offset; u32 dat_offset;
u16 tail_pad; u16 tail_pad;
u32 dummy_flags, chop_len; u16 dummy_flags, chop_len;
struct sk_buff *pkt_next, *tmp, *pkt_prev; struct sk_buff *pkt_next, *tmp, *pkt_prev;
skb_queue_walk_safe(pktq, pkt_next, tmp) { skb_queue_walk_safe(pktq, pkt_next, tmp) {
dummy_flags = *(u32 *)(pkt_next->cb); dummy_flags = *(u16 *)(pkt_next->cb);
if (dummy_flags & ALIGN_SKB_FLAG) { if (dummy_flags & ALIGN_SKB_FLAG) {
chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK; chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK;
if (chop_len) { if (chop_len) {
...@@ -2709,6 +2709,8 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt) ...@@ -2709,6 +2709,8 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
/* Priority based enq */ /* Priority based enq */
spin_lock_irqsave(&bus->txqlock, flags); spin_lock_irqsave(&bus->txqlock, flags);
/* reset bus_flags in packet cb */
*(u16 *)(pkt->cb) = 0;
if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) { if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) {
skb_pull(pkt, bus->tx_hdrlen); skb_pull(pkt, bus->tx_hdrlen);
brcmf_err("out of bus->txq !!!\n"); brcmf_err("out of bus->txq !!!\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment