Merge branch 'vlan-fix'
Toshiaki Makita says: ==================== Fix vlan tag handling for vlan packets without ethernet headers Eric Dumazet reported syzbot found a new bug which leads to underflow of size argument of memmove(), causing crash[1]. This can be triggered by tun devices. The underflow happened because skb_vlan_untag() did not expect vlan packets without ethernet headers, and tun can produce such packets. I also checked vlan_insert_inner_tag() and found a similar bug. This series fixes these problems. [1] https://marc.info/?l=linux-netdev&m=152221753920510&w=2 ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
52a9692a43
@ -323,13 +323,24 @@ static inline int __vlan_insert_inner_tag(struct sk_buff *skb,
|
||||
skb_push(skb, VLAN_HLEN);
|
||||
|
||||
/* Move the mac header sans proto to the beginning of the new header. */
|
||||
memmove(skb->data, skb->data + VLAN_HLEN, mac_len - ETH_TLEN);
|
||||
if (likely(mac_len > ETH_TLEN))
|
||||
memmove(skb->data, skb->data + VLAN_HLEN, mac_len - ETH_TLEN);
|
||||
skb->mac_header -= VLAN_HLEN;
|
||||
|
||||
veth = (struct vlan_ethhdr *)(skb->data + mac_len - ETH_HLEN);
|
||||
|
||||
/* first, the ethernet type */
|
||||
veth->h_vlan_proto = vlan_proto;
|
||||
if (likely(mac_len >= ETH_TLEN)) {
|
||||
/* h_vlan_encapsulated_proto should already be populated, and
|
||||
* skb->data has space for h_vlan_proto
|
||||
*/
|
||||
veth->h_vlan_proto = vlan_proto;
|
||||
} else {
|
||||
/* h_vlan_encapsulated_proto should not be populated, and
|
||||
* skb->data has no space for h_vlan_proto
|
||||
*/
|
||||
veth->h_vlan_encapsulated_proto = skb->protocol;
|
||||
}
|
||||
|
||||
/* now, the TCI */
|
||||
veth->h_vlan_TCI = htons(vlan_tci);
|
||||
|
@ -5028,8 +5028,10 @@ static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb)
|
||||
}
|
||||
|
||||
mac_len = skb->data - skb_mac_header(skb);
|
||||
memmove(skb_mac_header(skb) + VLAN_HLEN, skb_mac_header(skb),
|
||||
mac_len - VLAN_HLEN - ETH_TLEN);
|
||||
if (likely(mac_len > VLAN_HLEN + ETH_TLEN)) {
|
||||
memmove(skb_mac_header(skb) + VLAN_HLEN, skb_mac_header(skb),
|
||||
mac_len - VLAN_HLEN - ETH_TLEN);
|
||||
}
|
||||
skb->mac_header += VLAN_HLEN;
|
||||
return skb;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user