
From: Chengming Zhou <chengming.zhou@linux.dev> mainline inclusion from mainline-v6.10-rc1 commit 90e823498881fb8a91d83e9a8eed87c8c3ff2176 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IARC7N CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... -------------------------------- The commit 2c653d0ee2ae ("ksm: introduce ksm_max_page_sharing per page deduplication limit") introduced a possible failure case in the stable_tree_insert(), where we may free the new allocated stable_node_dup if we fail to prepare the missing chain node. Then that kfolio return and unlock with a freed stable_node set... And any MM activities can come in to access kfolio->mapping, so UAF. Fix it by moving folio_set_stable_node() to the end after stable_node is inserted successfully. Link: https://lkml.kernel.org/r/20240513-b4-ksm-stable-node-uaf-v1-1-f687de76f452@... Fixes: 2c653d0ee2ae ("ksm: introduce ksm_max_page_sharing per page deduplication limit") Signed-off-by: Chengming Zhou <chengming.zhou@linux.dev> Acked-by: David Hildenbrand <david@redhat.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Hugh Dickins <hughd@google.com> Cc: Stefan Roesch <shr@devkernel.io> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Conflicts: mm/ksm.c [HULK-4.19 didn't merge mainline inclusion commit 79899cce33e0887c06d41e767aa543aaaaef48e2("mm/ksm: convert chain series funcs and replace get_ksm_page")] Signed-off-by: Kaixiong Yu <yukaixiong@huawei.com> --- mm/ksm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm/ksm.c b/mm/ksm.c index 341e09c376e6..fc6b6526099f 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -1904,7 +1904,6 @@ static struct stable_node *stable_tree_insert(struct page *kpage) INIT_HLIST_HEAD(&stable_node_dup->hlist); stable_node_dup->kpfn = kpfn; - set_page_stable_node(kpage, stable_node_dup); stable_node_dup->rmap_hlist_len = 0; DO_NUMA(stable_node_dup->nid = nid); if (!need_chain) { @@ -1923,6 +1922,8 @@ static struct stable_node *stable_tree_insert(struct page *kpage) stable_node_chain_add_dup(stable_node_dup, stable_node); } + set_page_stable_node(kpage, stable_node_dup); + return stable_node_dup; } -- 2.34.1