net/packet: fix overflow in tpacket_rcv
[ Upstream commit5.4-rM2-2.2.x-imx-squashedacf69c9462
] Using tp_reserve to calculate netoff can overflow as tp_reserve is unsigned int and netoff is unsigned short. This may lead to macoff receving a smaller value then sizeof(struct virtio_net_hdr), and if po->has_vnet_hdr is set, an out-of-bounds write will occur when calling virtio_net_hdr_from_skb. The bug is fixed by converting netoff to unsigned int and checking if it exceeds USHRT_MAX. This addresses CVE-2020-14386 Fixes:8913336a7e
("packet: add PACKET_RESERVE sockopt") Signed-off-by: Or Cohen <orcohen@paloaltonetworks.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
parent
e3d109c348
commit
bc846b58fe
|
@ -2169,7 +2169,8 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||||
int skb_len = skb->len;
|
int skb_len = skb->len;
|
||||||
unsigned int snaplen, res;
|
unsigned int snaplen, res;
|
||||||
unsigned long status = TP_STATUS_USER;
|
unsigned long status = TP_STATUS_USER;
|
||||||
unsigned short macoff, netoff, hdrlen;
|
unsigned short macoff, hdrlen;
|
||||||
|
unsigned int netoff;
|
||||||
struct sk_buff *copy_skb = NULL;
|
struct sk_buff *copy_skb = NULL;
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
__u32 ts_status;
|
__u32 ts_status;
|
||||||
|
@ -2238,6 +2239,10 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||||
}
|
}
|
||||||
macoff = netoff - maclen;
|
macoff = netoff - maclen;
|
||||||
}
|
}
|
||||||
|
if (netoff > USHRT_MAX) {
|
||||||
|
atomic_inc(&po->tp_drops);
|
||||||
|
goto drop_n_restore;
|
||||||
|
}
|
||||||
if (po->tp_version <= TPACKET_V2) {
|
if (po->tp_version <= TPACKET_V2) {
|
||||||
if (macoff + snaplen > po->rx_ring.frame_size) {
|
if (macoff + snaplen > po->rx_ring.frame_size) {
|
||||||
if (po->copy_thresh &&
|
if (po->copy_thresh &&
|
||||||
|
|
Loading…
Reference in New Issue