Patch "neigh: do not modify unlinked entries" has been added to the 4.0-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
neigh: do not modify unlinked entries
to the 4.0-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:
neigh-do-not-modify-unlinked-entries.patch
and it can be found in the queue-4.0 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 Fri Jul 3 19:59:52 PDT 2015
From: Julian Anastasov <[email protected]>
Date: Tue, 16 Jun 2015 22:56:39 +0300
Subject: neigh: do not modify unlinked entries
From: Julian Anastasov <[email protected]>
[ Upstream commit 2c51a97f76d20ebf1f50fef908b986cb051fdff9 ]
The lockless lookups can return entry that is unlinked. Sometimes they get reference before last neigh_cleanup_and_release, sometimes they do not need reference. Later, any modification attempts may result in the following problems:
1. entry is not destroyed immediately because neigh_update can start the timer for dead entry, eg. on change to NUD_REACHABLE state. As result, entry lives for some time but is invisible and out of control.
2. __neigh_event_send can run in parallel with neigh_destroy while refcnt=0 but if timer is started and expired refcnt can reach 0 for second time leading to second neigh_destroy and possible crash.
Thanks to Eric Dumazet and Ying Xue for their work and analyze on the __neigh_event_send change.
--- net/core/neighbour.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
net/core/neighbour.c +13 -0
@@ -971,6 +971,8 @@ int __neigh_event_send(struct neighbour rc =0 ;if (neigh->nud_state & (NUD_CONNECTED |NUD_DELAY |NUD_PROBE )) goto out_unlock_bh; +if (neigh->dead) + goto out_dead;if (!(neigh->nud_state & (NUD_STALE |NUD_INCOMPLETE ))) { if (NEIGH_VAR(neigh->parms, MCAST_PROBES) +
@@ -1027,6 +1029,13 @@ out_unlock_bh:write_unlock (&neigh->lock);local_bh_enable ();return rc; + +out_dead: +if (neigh->nud_state &NUD_STALE ) + goto out_unlock_bh; +write_unlock_bh (&neigh->lock); +kfree_skb (skb); +return 1 ; }EXPORT_SYMBOL (__neigh_event_send);
@@ -1090,6 +1099,8 @@ int neigh_update(struct neighbour *neighif (!(flags &NEIGH_UPDATE_F_ADMIN ) && (old & (NUD_NOARP |NUD_PERMANENT ))) goto out; +if (neigh->dead) + goto out;if (!(new &NUD_VALID )) {neigh_del_timer (neigh);
@@ -1239,6 +1250,8 @@ EXPORT_SYMBOL(neigh_update);*/ void __neigh_set_probe_once (struct neighbour *neigh) { +if (neigh->dead) +return ; neigh->updated = jiffies;if (!(neigh->nud_state &NUD_FAILED ))return ;
Patches currently in stable-queue which might be from [email protected] are
queue-4.0/neigh-do-not-modify-unlinked-entries.patch queue-4.0/ip-report-the-original-address-of-icmp-messages.patch