[PATCH OLK-6.6 0/2] xfrm: Fix CVE-2026-43091 RCU use-after-free in policy netns exit
From: Sashiko Review <sashiko@example.com> This patch series fixes CVE-2026-43091 in the OLK-6.6 branch. * Patch 1: Add synchronize_rcu() before freeing policy hash tables to prevent RCU use-after-free during policy netns exit. * Patch 2: Move the RCU sync from per-netns .exit to .pre_exit to avoid O(N) RCU grace periods during batch netns cleanup. Steffen Klassert (1): xfrm: Wait for RCU readers during policy netns exit Usama Arif (1): xfrm: move policy_bydst RCU sync from per-netns .exit to .pre_exit net/xfrm/xfrm_policy.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) -- 2.43.0
From: Steffen Klassert <steffen.klassert@secunet.com> stable inclusion from stable-v6.6.136 commit b66920a3348c0f63ba18365248fa21fbf0b3a937 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/14643 CVE: CVE-2026-43091 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... -------------------------------- [ Upstream commit 069daad4f2ae9c5c108131995529d5f02392c446 ] xfrm_policy_fini() frees the policy_bydst hash tables after flushing the policy work items and deleting all policies, but it does not wait for concurrent RCU readers to leave their read-side critical sections first. The policy_bydst tables are published via rcu_assign_pointer() and are looked up through rcu_dereference_check(), so netns teardown must also wait for an RCU grace period before freeing the table memory. Fix this by adding synchronize_rcu() before freeing the policy hash tables. Fixes: e1e551bc5630 ("xfrm: policy: prepare policy_bydst hash for rcu lookups") Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> Reviewed-by: Florian Westphal <fw@strlen.de> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com> --- net/xfrm/xfrm_policy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index bd3d698887eb..8e6383b95d6f 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -4129,6 +4129,8 @@ static void xfrm_policy_fini(struct net *net) #endif xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, false); + synchronize_rcu(); + WARN_ON(!list_empty(&net->xfrm.policy_all)); for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { -- 2.43.0
From: Usama Arif <usama.arif@linux.dev> mainline inclusion from mainline-v7.1-rc6 commit 3e52417318473782012b236d0325bf7d2266a597 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/14643 CVE: CVE-2026-43091 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- The struct pernet_operations docstring in include/net/net_namespace.h explicitly warns against blocking RCU primitives in .exit handlers: Exit methods using blocking RCU primitives, such as synchronize_rcu(), should be implemented via exit_batch. [...] Please, avoid synchronize_rcu() at all, where it's possible. Note that a combination of pre_exit() and exit() can be used, since a synchronize_rcu() is guaranteed between the calls. xfrm_policy_fini() violates this: it calls synchronize_rcu() before freeing the policy_bydst hash tables (so no RCU reader is mid- traversal at free time), but runs from xfrm_net_ops.exit -- once per namespace -- so a cleanup_net() of N namespaces pays N full RCU grace periods serially. Use the documented pre_exit/exit split. Move the policy flush (and the workqueue drains it depends on) into a new .pre_exit handler; xfrm_policy_fini() then runs in .exit and frees the hash tables after the synchronize_rcu_expedited() that cleanup_net() guarantees between the two phases. Providing O(1) RCU grace periods per batch instead of O(N). Observed on Linux 6.18 with a workload doing unshare(CLONE_NEWNET) at ~13/sec sustained: cleanup_net() and the netns_wq rescuer kthread both stuck in xfrm_policy_fini()'s synchronize_rcu(), >300k struct net accumulated in the cleanup queue, Percpu in /proc/meminfo climbed to 130+ GB on 256-CPU hosts, and memcg OOMs followed. setup_net and __put_net counts were balanced, ruling out a refcount leak. Fixes: 069daad4f2ae ("xfrm: Wait for RCU readers during policy netns exit") Signed-off-by: Usama Arif <usama.arif@linux.dev> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com> --- net/xfrm/xfrm_policy.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 8e6383b95d6f..a6ded7e35bb4 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -4115,21 +4115,21 @@ static int __net_init xfrm_policy_init(struct net *net) return -ENOMEM; } -static void xfrm_policy_fini(struct net *net) +static void __net_exit xfrm_net_pre_exit(struct net *net) { - struct xfrm_pol_inexact_bin *b, *t; - unsigned int sz; - int dir; - disable_work_sync(&net->xfrm.policy_hthresh.work); - flush_work(&net->xfrm.policy_hash_work); #ifdef CONFIG_XFRM_SUB_POLICY xfrm_policy_flush(net, XFRM_POLICY_TYPE_SUB, false); #endif xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, false); +} - synchronize_rcu(); +static void xfrm_policy_fini(struct net *net) +{ + struct xfrm_pol_inexact_bin *b, *t; + unsigned int sz; + int dir; WARN_ON(!list_empty(&net->xfrm.policy_all)); @@ -4202,6 +4202,7 @@ static void __net_exit xfrm_net_exit(struct net *net) static struct pernet_operations __net_initdata xfrm_net_ops = { .init = xfrm_net_init, + .pre_exit = xfrm_net_pre_exit, .exit = xfrm_net_exit, }; -- 2.43.0
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/23839 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/UVD... 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://atomgit.com/openeuler/kernel/merge_requests/23839 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/UVD...
participants (2)
-
patchwork bot -
superdcc97@163.com