lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Tue, 13 Sep 2022 17:55:39 -0700 From: Kees Cook <keescook@...omium.org> To: Jason@...c4.com Cc: syzbot <syzbot+a448cda4dba2dac50de5@...kaller.appspotmail.com>, davem@...emloft.net, edumazet@...gle.com, kuba@...nel.org, linux-kernel@...r.kernel.org, linux-next@...r.kernel.org, netdev@...r.kernel.org, pabeni@...hat.com, sfr@...b.auug.org.au, syzkaller-bugs@...glegroups.com, wireguard@...ts.zx2c4.com Subject: Re: [syzbot] linux-next test error: WARNING in set_peer On Tue, Sep 13, 2022 at 12:51:42PM -0700, syzbot wrote: > memcpy: detected field-spanning write (size 28) of single field "&endpoint.addr" at drivers/net/wireguard/netlink.c:446 (size 16) This is one way to fix it: diff --git a/drivers/net/wireguard/netlink.c b/drivers/net/wireguard/netlink.c index 0c0644e762e5..dbbeba216530 100644 --- a/drivers/net/wireguard/netlink.c +++ b/drivers/net/wireguard/netlink.c @@ -434,16 +434,16 @@ static int set_peer(struct wg_device *wg, struct nlattr **attrs) } if (attrs[WGPEER_A_ENDPOINT]) { - struct sockaddr *addr = nla_data(attrs[WGPEER_A_ENDPOINT]); + struct endpoint *raw = nla_data(attrs[WGPEER_A_ENDPOINT]); size_t len = nla_len(attrs[WGPEER_A_ENDPOINT]); if ((len == sizeof(struct sockaddr_in) && - addr->sa_family == AF_INET) || + raw->addr.sa_family == AF_INET) || (len == sizeof(struct sockaddr_in6) && - addr->sa_family == AF_INET6)) { + raw->addr.sa_family == AF_INET6)) { struct endpoint endpoint = { { { 0 } } }; - memcpy(&endpoint.addr, addr, len); + memcpy(&endpoint.addrs, &raw->addrs, len); wg_socket_set_peer_endpoint(peer, &endpoint); } } diff --git a/drivers/net/wireguard/peer.h b/drivers/net/wireguard/peer.h index 76e4d3128ad4..4fbe7940828b 100644 --- a/drivers/net/wireguard/peer.h +++ b/drivers/net/wireguard/peer.h @@ -19,11 +19,13 @@ struct wg_device; struct endpoint { - union { - struct sockaddr addr; - struct sockaddr_in addr4; - struct sockaddr_in6 addr6; - }; + struct_group(addrs, + union { + struct sockaddr addr; + struct sockaddr_in addr4; + struct sockaddr_in6 addr6; + }; + ); union { struct { struct in_addr src4; diffoscope shows the bounds check gets updated to the full union size: │ - cmp $0x11,%edx │ + cmp $0x1d,%edx and the field name changes in the warning: $ strings clang/drivers/net/wireguard/netlink.o.after | grep ^field field "&endpoint.addrs" at drivers/net/wireguard/netlink.c:446 -- Kees Cook
Powered by blists - more mailing lists