mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
xfrm: validate selector family and prefixlen during match
syzbot reported a shift-out-of-bounds in xfrm_selector_match()
due to AF_UNSPEC selector with large prefixlen (e.g. 128) matched
against IPv4 flow (when XFRM_STATE_AF_UNSPEC is set).
Fix this by:
- Rejecting mismatched families in xfrm_selector_match.
- Returning false in addr4_match if prefixlen > 32.
- Returning false in addr_match if prefixlen > 128 (prevents overflow).
Fixes: 3f0ab59e65 ("xfrm: validate new SA's prefixlen using SA family when sel.family is unset")
Reported-by: syzbot+9383b1ff0df4b29ca5e6@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6a2fbe35.be3f099c.2836ae.0018.GAE@google.com/T/#u
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
0078004080
commit
40f0b10479
|
|
@ -943,6 +943,9 @@ static inline bool addr_match(const void *token1, const void *token2,
|
|||
unsigned int pdw;
|
||||
unsigned int pbi;
|
||||
|
||||
if (prefixlen > 128)
|
||||
return false;
|
||||
|
||||
pdw = prefixlen >> 5; /* num of whole u32 in prefix */
|
||||
pbi = prefixlen & 0x1f; /* num of bits in incomplete u32 in prefix */
|
||||
|
||||
|
|
@ -967,6 +970,10 @@ static inline bool addr4_match(__be32 a1, __be32 a2, u8 prefixlen)
|
|||
/* C99 6.5.7 (3): u32 << 32 is undefined behaviour */
|
||||
if (sizeof(long) == 4 && prefixlen == 0)
|
||||
return true;
|
||||
|
||||
if (prefixlen > 32)
|
||||
return false;
|
||||
|
||||
return !((a1 ^ a2) & htonl(~0UL << (32 - prefixlen)));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -242,6 +242,9 @@ __xfrm6_selector_match(const struct xfrm_selector *sel, const struct flowi *fl)
|
|||
bool xfrm_selector_match(const struct xfrm_selector *sel, const struct flowi *fl,
|
||||
unsigned short family)
|
||||
{
|
||||
if (family != sel->family && sel->family != AF_UNSPEC)
|
||||
return false;
|
||||
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
return __xfrm4_selector_match(sel, fl);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user