mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-27 08:14:35 +08:00
brcmfmac: use skb_cow() in brcmf_sdbrcm_txpkt() to assure alignment
In brcmf_sdbrcm_txpkt() a new packet is allocated and used to transmit to firmware freeing up the original packet. However, that packet is still referenced in firmware-signalling so this would result in a double free. Using skb_cow() avoids this as the packet reference is unchanged. Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Reviewed-by: Piotr Haber <phaber@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
a04278096c
commit
aeecc574a4
@ -1781,7 +1781,6 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
|
|||||||
u8 *frame;
|
u8 *frame;
|
||||||
u16 len, pad = 0;
|
u16 len, pad = 0;
|
||||||
u32 swheader;
|
u32 swheader;
|
||||||
struct sk_buff *new;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
brcmf_dbg(TRACE, "Enter\n");
|
brcmf_dbg(TRACE, "Enter\n");
|
||||||
@ -1795,26 +1794,14 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
|
|||||||
brcmf_dbg(INFO, "insufficient headroom %d for %d pad\n",
|
brcmf_dbg(INFO, "insufficient headroom %d for %d pad\n",
|
||||||
skb_headroom(pkt), pad);
|
skb_headroom(pkt), pad);
|
||||||
bus->sdiodev->bus_if->tx_realloc++;
|
bus->sdiodev->bus_if->tx_realloc++;
|
||||||
new = brcmu_pkt_buf_get_skb(pkt->len + BRCMF_SDALIGN);
|
ret = skb_cow(pkt, BRCMF_SDALIGN);
|
||||||
if (!new) {
|
if (ret)
|
||||||
brcmf_err("couldn't allocate new %d-byte packet\n",
|
|
||||||
pkt->len + BRCMF_SDALIGN);
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
pad = ((unsigned long)frame % BRCMF_SDALIGN);
|
||||||
|
|
||||||
pkt_align(new, pkt->len, BRCMF_SDALIGN);
|
|
||||||
memcpy(new->data, pkt->data, pkt->len);
|
|
||||||
brcmu_pkt_buf_free_skb(pkt);
|
|
||||||
pkt = new;
|
|
||||||
frame = (u8 *) (pkt->data);
|
|
||||||
/* precondition: (frame % BRCMF_SDALIGN) == 0) */
|
|
||||||
pad = 0;
|
|
||||||
} else {
|
|
||||||
skb_push(pkt, pad);
|
|
||||||
frame = (u8 *) (pkt->data);
|
|
||||||
memset(frame + SDPCM_HDRLEN, 0, pad);
|
|
||||||
}
|
}
|
||||||
|
skb_push(pkt, pad);
|
||||||
|
frame = (u8 *) (pkt->data);
|
||||||
|
memset(frame, 0, pad + SDPCM_HDRLEN);
|
||||||
}
|
}
|
||||||
/* precondition: pad < BRCMF_SDALIGN */
|
/* precondition: pad < BRCMF_SDALIGN */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user