From: Eric Dumazet edumazet@google.com
mainline inclusion from mainline-v6.6-rc5 commit 5baa0433a15eadd729625004c37463acb982eca7 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAZ542
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
n->output field can be read locklessly, while a writer might change the pointer concurrently.
Add missing annotations to prevent load-store tearing.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Dumazet edumazet@google.com Reviewed-by: David Ahern dsahern@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Conflicts: net/core/neighbour.c [conflicts due to mergered 09eed1192cec ("neighbour: switch to standard rcu, instead of rcu_bh")] Signed-off-by: Wang Liang wangliang74@huawei.com --- include/net/neighbour.h | 2 +- net/bridge/br_netfilter_hooks.c | 2 +- net/core/neighbour.c | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 8e4404efd910..ef310154818e 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -514,7 +514,7 @@ static inline int neigh_output(struct neighbour *n, struct sk_buff *skb, READ_ONCE(hh->hh_len)) return neigh_hh_output(hh, skb);
- return n->output(n, skb); + return READ_ONCE(n->output)(n, skb); }
static inline struct neighbour * diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c index 119b1a36a126..a65a77eb740d 100644 --- a/net/bridge/br_netfilter_hooks.c +++ b/net/bridge/br_netfilter_hooks.c @@ -305,7 +305,7 @@ int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_ /* tell br_dev_xmit to continue with forwarding */ nf_bridge->bridged_dnat = 1; /* FIXME Need to refragment */ - ret = neigh->output(neigh, skb); + ret = READ_ONCE(neigh->output)(neigh, skb); } neigh_release(neigh); return ret; diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 432e3a64dc4a..168868fb8e6c 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -364,7 +364,7 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev, */ __skb_queue_purge(&n->arp_queue); n->arp_queue_len_bytes = 0; - n->output = neigh_blackhole; + WRITE_ONCE(n->output, neigh_blackhole); if (n->nud_state & NUD_VALID) n->nud_state = NUD_NOARP; else @@ -875,7 +875,7 @@ static void neigh_suspect(struct neighbour *neigh) { neigh_dbg(2, "neigh %p is suspected\n", neigh);
- neigh->output = neigh->ops->output; + WRITE_ONCE(neigh->output, neigh->ops->output); }
/* Neighbour state is OK; @@ -887,7 +887,7 @@ static void neigh_connect(struct neighbour *neigh) { neigh_dbg(2, "neigh %p is connected\n", neigh);
- neigh->output = neigh->ops->connected_output; + WRITE_ONCE(neigh->output, neigh->ops->connected_output); }
static void neigh_periodic_work(struct work_struct *work) @@ -1402,7 +1402,7 @@ static int __neigh_update(struct neighbour *neigh, const u8 *lladdr, if (n2) n1 = n2; } - n1->output(n1, skb); + READ_ONCE(n1->output)(n1, skb); if (n2) neigh_release(n2); rcu_read_unlock(); @@ -3027,7 +3027,7 @@ int neigh_xmit(int index, struct net_device *dev, rcu_read_unlock_bh(); goto out_kfree_skb; } - err = neigh->output(neigh, skb); + err = READ_ONCE(neigh->output)(neigh, skb); rcu_read_unlock_bh(); } else if (index == NEIGH_LINK_TABLE) {
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/12349 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/F...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/12349 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/F...