aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugenio Pérez <eperezma@redhat.com>2020-02-21 12:06:56 +0100
committerBen Hutchings <ben@decadent.org.uk>2020-04-28 19:03:43 +0100
commite4d98e5299b19e1caad03f0b38fd41b046d0de56 (patch)
treecb556ad29d629407c59ba73179bf64109b3f0379
parent2f9ac30a54dc0181ddac3705cdcf4775d863c530 (diff)
downloadlinux-stable-e4d98e5299b19e1caad03f0b38fd41b046d0de56.tar.gz
vhost: Check docket sk_family instead of call getname
commit 42d84c8490f9f0931786f1623191fcab397c3d64 upstream. Doing so, we save one call to get data we already have in the struct. Also, since there is no guarantee that getname use sockaddr_ll parameter beyond its size, we add a little bit of security here. It should do not do beyond MAX_ADDR_LEN, but syzbot found that ax25_getname writes more (72 bytes, the size of full_sockaddr_ax25, versus 20 + 32 bytes of sockaddr_ll + MAX_ADDR_LEN in syzbot repro). Fixes: 3a4d5c94e9593 ("vhost_net: a kernel-level virtio server") Reported-by: syzbot+f2a62d07a5198c819c7b@syzkaller.appspotmail.com Signed-off-by: Eugenio Pérez <eperezma@redhat.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net> [bwh: Backported to 3.16: Also delete "uaddr_len" variable] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--drivers/vhost/net.c13
1 files changed, 2 insertions, 11 deletions
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 3f16c299263f4..c99c71afcd5c9 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -843,11 +843,7 @@ static int vhost_net_release(struct inode *inode, struct file *f)
static struct socket *get_raw_socket(int fd)
{
- struct {
- struct sockaddr_ll sa;
- char buf[MAX_ADDR_LEN];
- } uaddr;
- int uaddr_len = sizeof uaddr, r;
+ int r;
struct socket *sock = sockfd_lookup(fd, &r);
if (!sock)
@@ -859,12 +855,7 @@ static struct socket *get_raw_socket(int fd)
goto err;
}
- r = sock->ops->getname(sock, (struct sockaddr *)&uaddr.sa,
- &uaddr_len, 0);
- if (r)
- goto err;
-
- if (uaddr.sa.sll_family != AF_PACKET) {
+ if (sock->sk->sk_family != AF_PACKET) {
r = -EPFNOSUPPORT;
goto err;
}