diff options
| author | Sabrina Dubroca <sd@queasysnail.net> | 2025-08-29 10:54:15 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-10-02 13:42:50 +0200 |
| commit | 0baf92d0b1590b903c1f4ead75e61715e50e8146 (patch) | |
| tree | 72f1e304781b03aace591b7b45a67d8e8b3eaba5 /net | |
| parent | f64abeebf763c3e1df52ff6e815238af384ac642 (diff) | |
| download | linux-0baf92d0b1590b903c1f4ead75e61715e50e8146.tar.gz linux-0baf92d0b1590b903c1f4ead75e61715e50e8146.tar.bz2 linux-0baf92d0b1590b903c1f4ead75e61715e50e8146.zip | |
xfrm: xfrm_alloc_spi shouldn't use 0 as SPI
[ Upstream commit cd8ae32e4e4652db55bce6b9c79267d8946765a9 ]
x->id.spi == 0 means "no SPI assigned", but since commit
94f39804d891 ("xfrm: Duplicate SPI Handling"), we now create states
and add them to the byspi list with this value.
__xfrm_state_delete doesn't remove those states from the byspi list,
since they shouldn't be there, and this shows up as a UAF the next
time we go through the byspi list.
Reported-by: syzbot+a25ee9d20d31e483ba7b@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=a25ee9d20d31e483ba7b
Fixes: 94f39804d891 ("xfrm: Duplicate SPI Handling")
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net')
| -rw-r--r-- | net/xfrm/xfrm_state.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index acfbe1f013d1..ded559f55767 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -2296,6 +2296,8 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high, for (h = 0; h < range; h++) { u32 spi = (low == high) ? low : get_random_u32_inclusive(low, high); + if (spi == 0) + goto next; newspi = htonl(spi); spin_lock_bh(&net->xfrm.xfrm_state_lock); @@ -2311,6 +2313,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high, xfrm_state_put(x0); spin_unlock_bh(&net->xfrm.xfrm_state_lock); +next: if (signal_pending(current)) { err = -ERESTARTSYS; goto unlock; |
