Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

vhost: Check docket sk_family instead of call getname

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>

authored by

Eugenio Pérez and committed by
David S. Miller
42d84c84 0c0ddd6a

+1 -9
+1 -9
drivers/vhost/net.c
··· 1414 1414 1415 1415 static struct socket *get_raw_socket(int fd) 1416 1416 { 1417 - struct { 1418 - struct sockaddr_ll sa; 1419 - char buf[MAX_ADDR_LEN]; 1420 - } uaddr; 1421 1417 int r; 1422 1418 struct socket *sock = sockfd_lookup(fd, &r); 1423 1419 ··· 1426 1430 goto err; 1427 1431 } 1428 1432 1429 - r = sock->ops->getname(sock, (struct sockaddr *)&uaddr.sa, 0); 1430 - if (r < 0) 1431 - goto err; 1432 - 1433 - if (uaddr.sa.sll_family != AF_PACKET) { 1433 + if (sock->sk->sk_family != AF_PACKET) { 1434 1434 r = -EPFNOSUPPORT; 1435 1435 goto err; 1436 1436 }