Commit eb2d16a7 authored by Eric Dumazet's avatar Eric Dumazet Committed by Steffen Klassert
Browse files

af_key: validate families in pfkey_send_migrate()



syzbot was able to trigger a crash in skb_put() [1]

Issue is that pfkey_send_migrate() does not check old/new families,
and that set_ipsecrequest() @family argument was truncated,
thus possibly overfilling the skb.

Validate families early, do not wait set_ipsecrequest().

[1]

skbuff: skb_over_panic: text:ffffffff8a752120 len:392 put:16 head:ffff88802a4ad040 data:ffff88802a4ad040 tail:0x188 end:0x180 dev:<NULL>
 kernel BUG at net/core/skbuff.c:214 !
Call Trace:
 <TASK>
  skb_over_panic net/core/skbuff.c:219 [inline]
  skb_put+0x159/0x210 net/core/skbuff.c:2655
  skb_put_zero include/linux/skbuff.h:2788 [inline]
  set_ipsecrequest net/key/af_key.c:3532 [inline]
  pfkey_send_migrate+0x1270/0x2e50 net/key/af_key.c:3636
  km_migrate+0x155/0x260 net/xfrm/xfrm_state.c:2848
  xfrm_migrate+0x2140/0x2450 net/xfrm/xfrm_policy.c:4705
  xfrm_do_migrate+0x8ff/0xaa0 net/xfrm/xfrm_user.c:3150

Fixes: 08de61be ("[PFKEYV2]: Extension for dynamic update of endpoint address(es)")
Reported-by: default avatar <syzbot+b518dfc8e021988fbd55@syzkaller.appspotmail.com>
Closes: https://lore.kernel.org/netdev/69b5933c.050a0220.248e02.00f2.GAE@google.com/T/#u


Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
parent 29fe3a61
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -3518,7 +3518,7 @@ static int set_sadb_kmaddress(struct sk_buff *skb, const struct xfrm_kmaddress *

static int set_ipsecrequest(struct sk_buff *skb,
			    uint8_t proto, uint8_t mode, int level,
			    uint32_t reqid, uint8_t family,
			    uint32_t reqid, sa_family_t family,
			    const xfrm_address_t *src, const xfrm_address_t *dst)
{
	struct sadb_x_ipsecrequest *rq;
@@ -3583,12 +3583,17 @@ static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,

	/* ipsecrequests */
	for (i = 0, mp = m; i < num_bundles; i++, mp++) {
		/* old locator pair */
		size_pol += sizeof(struct sadb_x_ipsecrequest) +
			    pfkey_sockaddr_pair_size(mp->old_family);
		/* new locator pair */
		size_pol += sizeof(struct sadb_x_ipsecrequest) +
			    pfkey_sockaddr_pair_size(mp->new_family);
		int pair_size;

		pair_size = pfkey_sockaddr_pair_size(mp->old_family);
		if (!pair_size)
			return -EINVAL;
		size_pol += sizeof(struct sadb_x_ipsecrequest) + pair_size;

		pair_size = pfkey_sockaddr_pair_size(mp->new_family);
		if (!pair_size)
			return -EINVAL;
		size_pol += sizeof(struct sadb_x_ipsecrequest) + pair_size;
	}

	size += sizeof(struct sadb_msg) + size_pol;