Patch "ipv6: Fix idev->addr_list corruption" has been added to the 4.10-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
ipv6: Fix idev->addr_list corruption
to the 4.10-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
ipv6-fix-idev-addr_list-corruption.patch
and it can be found in the queue-4.10 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Sat Apr 29 08:22:40 CEST 2017
From: Rabin Vincent <[email protected]>
Date: Mon, 10 Apr 2017 08:36:39 +0200
Subject: ipv6: Fix idev->addr_list corruption
From: Rabin Vincent <[email protected]>
[ Upstream commit a2d6cbb0670d54806f18192cb0db266b4a6d285a ]
addrconf_ifdown() removes elements from the idev->addr_list without holding the idev->lock.
If this happens while the loop in __ipv6_dev_get_saddr() is handling the same element, that function ends up in an infinite loop:
NMI watchdog: BUG: soft lockup - CPU#1 stuck for 23s! [test:1719]
Call Trace: ipv6_get_saddr_eval+0x13c/0x3a0 __ipv6_dev_get_saddr+0xe4/0x1f0 ipv6_dev_get_saddr+0x1b4/0x204 ip6_dst_lookup_tail+0xcc/0x27c ip6_dst_lookup_flow+0x38/0x80 udpv6_sendmsg+0x708/0xba8 sock_sendmsg+0x18/0x30 SyS_sendto+0xb8/0xf8 syscall_common+0x34/0x58
--- net/ipv6/addrconf.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
net/ipv6/addrconf.c +7 -4
@@ -3618,14 +3618,19 @@ restart:INIT_LIST_HEAD (&del_list);list_for_each_entry_safe (ifa, tmp, &idev->addr_list, if_list) {struct rt6_info *rt =NULL ; +bool keep;addrconf_del_dad_work (ifa); + keep = keep_addr && (ifa->flags &IFA_F_PERMANENT ) && + !addr_is_local (&ifa->addr); +if (!keep) +list_move (&ifa->if_list, &del_list); +write_unlock_bh (&idev->lock);spin_lock_bh (&ifa->lock); -if (keep_addr && (ifa->flags &IFA_F_PERMANENT ) && - !addr_is_local (&ifa->addr)) { +if (keep) {/* set state to skip the notifier below */ state =INET6_IFADDR_STATE_DEAD ; ifa->state =0 ;
@@ -3637,8 +3642,6 @@ restart: }else { state = ifa->state; ifa->state =INET6_IFADDR_STATE_DEAD ; - -list_move (&ifa->if_list, &del_list); }spin_unlock_bh (&ifa->lock);
Patches currently in stable-queue which might be from [email protected] are
queue-4.10/ipv6-fix-idev-addr_list-corruption.patch