diff options
author | Arend van Spriel <arend@broadcom.com> | 2013-01-02 09:22:46 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-01-07 15:16:57 -0500 |
commit | 12b33dacb4bb3780512d3c6a4d064d9ed1172c0e (patch) | |
tree | 45312582ab5b8a8395531cce16675a4615b60dfe /drivers/net | |
parent | 7833b5799fb4dd201d6808c164712ea9d0c3dec0 (diff) |
brcmfmac: cleanup netdev transmit callback
The header of the ethernet packet is processed conditionally, but
the check is wrong as it checks skb length is at least ETH_ALEN. It
should check it is at least sizeof struct ethhdr instead.
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index a1ca6912ef28..9ca74118e131 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
@@ -165,6 +165,7 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
165 | int ret; | 165 | int ret; |
166 | struct brcmf_if *ifp = netdev_priv(ndev); | 166 | struct brcmf_if *ifp = netdev_priv(ndev); |
167 | struct brcmf_pub *drvr = ifp->drvr; | 167 | struct brcmf_pub *drvr = ifp->drvr; |
168 | struct ethhdr *eh; | ||
168 | 169 | ||
169 | brcmf_dbg(TRACE, "Enter\n"); | 170 | brcmf_dbg(TRACE, "Enter\n"); |
170 | 171 | ||
@@ -202,17 +203,20 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
202 | } | 203 | } |
203 | } | 204 | } |
204 | 205 | ||
205 | /* Update multicast statistic */ | 206 | /* validate length for ether packet */ |
206 | if (skb->len >= ETH_ALEN) { | 207 | if (skb->len < sizeof(*eh)) { |
207 | u8 *pktdata = (u8 *)(skb->data); | 208 | ret = -EINVAL; |
208 | struct ethhdr *eh = (struct ethhdr *)pktdata; | 209 | dev_kfree_skb(skb); |
209 | 210 | goto done; | |
210 | if (is_multicast_ether_addr(eh->h_dest)) | ||
211 | drvr->tx_multicast++; | ||
212 | if (ntohs(eh->h_proto) == ETH_P_PAE) | ||
213 | atomic_inc(&drvr->pend_8021x_cnt); | ||
214 | } | 211 | } |
215 | 212 | ||
213 | /* handle ethernet header */ | ||
214 | eh = (struct ethhdr *)(skb->data); | ||
215 | if (is_multicast_ether_addr(eh->h_dest)) | ||
216 | drvr->tx_multicast++; | ||
217 | if (ntohs(eh->h_proto) == ETH_P_PAE) | ||
218 | atomic_inc(&drvr->pend_8021x_cnt); | ||
219 | |||
216 | /* If the protocol uses a data header, apply it */ | 220 | /* If the protocol uses a data header, apply it */ |
217 | brcmf_proto_hdrpush(drvr, ifp->idx, skb); | 221 | brcmf_proto_hdrpush(drvr, ifp->idx, skb); |
218 | 222 | ||