]>
Commit | Line | Data |
---|---|---|
f04023b1 AF |
1 | From acf69c946233259ab4d64f8869d4037a198c7f06 Mon Sep 17 00:00:00 2001 |
2 | From: Or Cohen <orcohen@paloaltonetworks.com> | |
3 | Date: Thu, 3 Sep 2020 21:05:28 -0700 | |
4 | Subject: net/packet: fix overflow in tpacket_rcv | |
5 | ||
6 | Using tp_reserve to calculate netoff can overflow as | |
7 | tp_reserve is unsigned int and netoff is unsigned short. | |
8 | ||
9 | This may lead to macoff receving a smaller value then | |
10 | sizeof(struct virtio_net_hdr), and if po->has_vnet_hdr | |
11 | is set, an out-of-bounds write will occur when | |
12 | calling virtio_net_hdr_from_skb. | |
13 | ||
14 | The bug is fixed by converting netoff to unsigned int | |
15 | and checking if it exceeds USHRT_MAX. | |
16 | ||
17 | This addresses CVE-2020-14386 | |
18 | ||
19 | Fixes: 8913336a7e8d ("packet: add PACKET_RESERVE sockopt") | |
20 | Signed-off-by: Or Cohen <orcohen@paloaltonetworks.com> | |
21 | Signed-off-by: Eric Dumazet <edumazet@google.com> | |
22 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
23 | --- | |
24 | net/packet/af_packet.c | 7 ++++++- | |
25 | 1 file changed, 6 insertions(+), 1 deletion(-) | |
26 | ||
27 | diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c | |
28 | index da8254e680f94..2b33e977a9059 100644 | |
29 | --- a/net/packet/af_packet.c | |
30 | +++ b/net/packet/af_packet.c | |
31 | @@ -2170,7 +2170,8 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, | |
32 | int skb_len = skb->len; | |
33 | unsigned int snaplen, res; | |
34 | unsigned long status = TP_STATUS_USER; | |
35 | - unsigned short macoff, netoff, hdrlen; | |
36 | + unsigned short macoff, hdrlen; | |
37 | + unsigned int netoff; | |
38 | struct sk_buff *copy_skb = NULL; | |
39 | struct timespec64 ts; | |
40 | __u32 ts_status; | |
41 | @@ -2239,6 +2240,10 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, | |
42 | } | |
43 | macoff = netoff - maclen; | |
44 | } | |
45 | + if (netoff > USHRT_MAX) { | |
46 | + atomic_inc(&po->tp_drops); | |
47 | + goto drop_n_restore; | |
48 | + } | |
49 | if (po->tp_version <= TPACKET_V2) { | |
50 | if (macoff + snaplen > po->rx_ring.frame_size) { | |
51 | if (po->copy_thresh && | |
52 | -- | |
53 | cgit 1.2.3-1.el7 | |
54 |