Skip to content

Commit eb2d16a

Browse files
edumazetklassert
authored andcommitted
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: 08de61b ("[PFKEYV2]: Extension for dynamic update of endpoint address(es)") Reported-by: [email protected] Closes: https://lore.kernel.org/netdev/[email protected]/T/#u Signed-off-by: Eric Dumazet <[email protected]> Cc: Steffen Klassert <[email protected]> Cc: Herbert Xu <[email protected]> Signed-off-by: Steffen Klassert <[email protected]>
1 parent 29fe3a6 commit eb2d16a

1 file changed

Lines changed: 12 additions & 7 deletions

File tree

net/key/af_key.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3518,7 +3518,7 @@ static int set_sadb_kmaddress(struct sk_buff *skb, const struct xfrm_kmaddress *
35183518

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

35843584
/* ipsecrequests */
35853585
for (i = 0, mp = m; i < num_bundles; i++, mp++) {
3586-
/* old locator pair */
3587-
size_pol += sizeof(struct sadb_x_ipsecrequest) +
3588-
pfkey_sockaddr_pair_size(mp->old_family);
3589-
/* new locator pair */
3590-
size_pol += sizeof(struct sadb_x_ipsecrequest) +
3591-
pfkey_sockaddr_pair_size(mp->new_family);
3586+
int pair_size;
3587+
3588+
pair_size = pfkey_sockaddr_pair_size(mp->old_family);
3589+
if (!pair_size)
3590+
return -EINVAL;
3591+
size_pol += sizeof(struct sadb_x_ipsecrequest) + pair_size;
3592+
3593+
pair_size = pfkey_sockaddr_pair_size(mp->new_family);
3594+
if (!pair_size)
3595+
return -EINVAL;
3596+
size_pol += sizeof(struct sadb_x_ipsecrequest) + pair_size;
35923597
}
35933598

35943599
size += sizeof(struct sadb_msg) + size_pol;

0 commit comments

Comments
 (0)