Message ID | 20210908101534.185105-1-lee.jones@linaro.org |
---|---|
State | New |
Headers | show |
Series | [1/1] igmp: Add ip_mc_list lock in ip_check_mc_rcu | expand |
On Wed, Sep 08, 2021 at 11:15:34AM +0100, Lee Jones wrote: > From: Liu Jian <liujian56@huawei.com> > > [ Upstream commit 23d2b94043ca8835bd1e67749020e839f396a1c2 ] > > I got below panic when doing fuzz test: > > Kernel panic - not syncing: panic_on_warn set ... > CPU: 0 PID: 4056 Comm: syz-executor.3 Tainted: G B 5.14.0-rc1-00195-gcff5c4254439-dirty #2 > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014 > Call Trace: > dump_stack_lvl+0x7a/0x9b > panic+0x2cd/0x5af > end_report.cold+0x5a/0x5a > kasan_report+0xec/0x110 > ip_check_mc_rcu+0x556/0x5d0 > __mkroute_output+0x895/0x1740 > ip_route_output_key_hash_rcu+0x2d0/0x1050 > ip_route_output_key_hash+0x182/0x2e0 > ip_route_output_flow+0x28/0x130 > udp_sendmsg+0x165d/0x2280 > udpv6_sendmsg+0x121e/0x24f0 > inet6_sendmsg+0xf7/0x140 > sock_sendmsg+0xe9/0x180 > ____sys_sendmsg+0x2b8/0x7a0 > ___sys_sendmsg+0xf0/0x160 > __sys_sendmmsg+0x17e/0x3c0 > __x64_sys_sendmmsg+0x9e/0x100 > do_syscall_64+0x3b/0x90 > entry_SYSCALL_64_after_hwframe+0x44/0xae > RIP: 0033:0x462eb9 > Code: f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 48 89 f8 > 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> > 3d 01 f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48 > RSP: 002b:00007f3df5af1c58 EFLAGS: 00000246 ORIG_RAX: 0000000000000133 > RAX: ffffffffffffffda RBX: 000000000073bf00 RCX: 0000000000462eb9 > RDX: 0000000000000312 RSI: 0000000020001700 RDI: 0000000000000007 > RBP: 0000000000000004 R08: 0000000000000000 R09: 0000000000000000 > R10: 0000000000000000 R11: 0000000000000246 R12: 00007f3df5af26bc > R13: 00000000004c372d R14: 0000000000700b10 R15: 00000000ffffffff > > It is one use-after-free in ip_check_mc_rcu. > In ip_mc_del_src, the ip_sf_list of pmc has been freed under pmc->lock protection. > But access to ip_sf_list in ip_check_mc_rcu is not protected by the lock. > > Cc: <stable@vger.kernel.org> # 4.4+ > Signed-off-by: Liu Jian <liujian56@huawei.com> > Signed-off-by: David S. Miller <davem@davemloft.net> > Signed-off-by: Lee Jones <lee.jones@linaro.org> > --- > net/ipv4/igmp.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c > index 00576bae183d3..0c321996c6eb0 100644 > --- a/net/ipv4/igmp.c > +++ b/net/ipv4/igmp.c > @@ -2720,6 +2720,7 @@ int ip_check_mc_rcu(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u > rv = 1; > } else if (im) { > if (src_addr) { > + spin_lock_bh(&im->lock); > for (psf = im->sources; psf; psf = psf->sf_next) { > if (psf->sf_inaddr == src_addr) > break; > @@ -2730,6 +2731,7 @@ int ip_check_mc_rcu(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u > im->sfcount[MCAST_EXCLUDE]; > else > rv = im->sfcount[MCAST_EXCLUDE] != 0; > + spin_unlock_bh(&im->lock); > } else > rv = 1; /* unspecified source; tentatively allow */ > } > -- > 2.33.0.153.gba50c8fa24-goog > Now queued up, thanks. greg k-h
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 00576bae183d3..0c321996c6eb0 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -2720,6 +2720,7 @@ int ip_check_mc_rcu(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u rv = 1; } else if (im) { if (src_addr) { + spin_lock_bh(&im->lock); for (psf = im->sources; psf; psf = psf->sf_next) { if (psf->sf_inaddr == src_addr) break; @@ -2730,6 +2731,7 @@ int ip_check_mc_rcu(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u im->sfcount[MCAST_EXCLUDE]; else rv = im->sfcount[MCAST_EXCLUDE] != 0; + spin_unlock_bh(&im->lock); } else rv = 1; /* unspecified source; tentatively allow */ }