From: Sabrina Dubroca <sd@queasysnail.net>
To: steffen.klassert@secunet.com, pabeni@redhat.com,
syzbot <syzbot+cc39f136925517aed571@syzkaller.appspotmail.com>
Cc: davem@davemloft.net, edumazet@google.com,
herbert@gondor.apana.org.au, kuba@kernel.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
syzkaller-bugs@googlegroups.com
Subject: Re: [syzbot] [net?] UBSAN: shift-out-of-bounds in xfrm_selector_match (2)
Date: Wed, 25 Sep 2024 13:08:48 +0200 [thread overview]
Message-ID: <ZvPvQMDvWRygp4IC@hog> (raw)
In-Reply-To: <66f33458.050a0220.457fc.001e.GAE@google.com>
2024-09-24, 14:51:20 -0700, syzbot wrote:
> syzbot has found a reproducer for the following issue on:
>
> HEAD commit: 151ac45348af net: sparx5: Fix invalid timestamps
> git tree: net-next
> console+strace: https://syzkaller.appspot.com/x/log.txt?x=15808a80580000
> kernel config: https://syzkaller.appspot.com/x/.config?x=37c006d80708398d
> dashboard link: https://syzkaller.appspot.com/bug?extid=cc39f136925517aed571
> compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
> syz repro: https://syzkaller.appspot.com/x/repro.syz?x=122ad2a9980000
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=1387b107980000
syzbot managed to create an SA with:
usersa.sel.family = 0
usersa.sel.prefixlen_s = 128
usersa.family = AF_INET
Because of the AF_UNSPEC selector, verify_newsa_info doesn't put
limits on prefixlen_{s,d}. But then copy_from_user_state sets
x->sel.family to usersa.family (AF_INET).
So I think verify_newsa_info should do the same conversion before
checking prefixlen:
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 55f039ec3d59..8d06a37adbd9 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -201,6 +201,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
{
int err;
u8 sa_dir = attrs[XFRMA_SA_DIR] ? nla_get_u8(attrs[XFRMA_SA_DIR]) : 0;
+ u16 family = p->sel.family;
err = -EINVAL;
switch (p->family) {
@@ -221,7 +222,10 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
goto out;
}
- switch (p->sel.family) {
+ if (!family && !(p->flags & XFRM_STATE_AF_UNSPEC))
+ family = p->family;
+
+ switch (family) {
case AF_UNSPEC:
break;
Steffen, does that make sense?
Without this, we have prefixlen=128 when we get to addr4_match, which
does a shift of (32 - prefixlen), so we get
UBSAN: shift-out-of-bounds in ./include/net/xfrm.h:900:23
shift exponent -96 is negative
Maybe a check for prefixlen < 128 would also be useful in the
XFRM_STATE_AF_UNSPEC case, to avoid the same problems with syzbot
passing prefixlen=200 for an ipv6 SA. I don't know how
XFRM_STATE_AF_UNSPEC is used, so I'm not sure what restrictions we can
put. If we end up with prefixlen = 100 used from ipv4 we'll still have
the same issues.
> __ip4_datagram_connect+0x96c/0x1260 net/ipv4/datagram.c:49
> __ip6_datagram_connect+0x194/0x1230
> ip6_datagram_connect net/ipv6/datagram.c:279 [inline]
> ip6_datagram_connect_v6_only+0x63/0xa0 net/ipv6/datagram.c:291
This path also looks a bit dubious. From the reproducer, we have a
rawv6 socket trying to connect to a v4mapped address, despite having
ip6_datagram_connect_v6_only as its ->connect.
pingv6 sockets also use ip6_datagram_connect_v6_only and set
sk->sk_ipv6only=1 (in net/ipv4/ping.c ping_init_sock), but rawv6 don't
have this, so __ip6_datagram_connect can end up in
__ip4_datagram_connect. I guess it would make sense to set it in rawv6
too. rawv6_bind already rejected v4mapped addresses.
And then we could add a DEBUG_NET_WARN_ON_ONCE(!ipv6_only_sock(sk)) in
ip6_datagram_connect_v6_only, or maybe even call ipv6_addr_type to
reject v4mapped addresses and reject them like the non-AF_INET6 case.
--
Sabrina
next prev parent reply other threads:[~2024-09-25 11:10 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-16 22:47 [syzbot] [net?] UBSAN: shift-out-of-bounds in xfrm_selector_match (2) syzbot
2024-09-24 21:51 ` syzbot
2024-09-25 11:08 ` Sabrina Dubroca [this message]
2024-09-27 7:30 ` Steffen Klassert
2024-09-27 8:38 ` Sabrina Dubroca
2024-10-01 17:10 ` Sabrina Dubroca
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZvPvQMDvWRygp4IC@hog \
--to=sd@queasysnail.net \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=herbert@gondor.apana.org.au \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=steffen.klassert@secunet.com \
--cc=syzbot+cc39f136925517aed571@syzkaller.appspotmail.com \
--cc=syzkaller-bugs@googlegroups.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.