On 2024/5/15 04:46, David Hildenbrand wrote: > On 13.05.24 05:07, Chengming Zhou wrote: >> 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. >> >> Fixes: 2c653d0ee2ae ("ksm: introduce ksm_max_page_sharing per page deduplication limit") >> Signed-off-by: Chengming Zhou <chengming.zhou@xxxxxxxxx> >> --- >> mm/ksm.c | 3 ++- >> 1 file changed, 2 insertions(+), 1 deletion(-) >> >> diff --git a/mm/ksm.c b/mm/ksm.c >> index e1034bf1c937..a8b76af5cf64 100644 >> --- a/mm/ksm.c >> +++ b/mm/ksm.c >> @@ -2153,7 +2153,6 @@ static struct ksm_stable_node *stable_tree_insert(struct folio *kfolio) >> INIT_HLIST_HEAD(&stable_node_dup->hlist); >> stable_node_dup->kpfn = kpfn; >> - folio_set_stable_node(kfolio, stable_node_dup); >> stable_node_dup->rmap_hlist_len = 0; >> DO_NUMA(stable_node_dup->nid = nid); >> if (!need_chain) { >> @@ -2172,6 +2171,8 @@ static struct ksm_stable_node *stable_tree_insert(struct folio *kfolio) >> stable_node_chain_add_dup(stable_node_dup, stable_node); >> } >> + folio_set_stable_node(kfolio, stable_node_dup); >> + >> return stable_node_dup; > > Looks correct to me. > > We might now link the node before the folio->mapping is set up. Do we care? Don't think so. Yeah, it shouldn't be a problem, although it doesn't look very nice. Another way to fix maybe "folio_set_stable_node(folio, NULL)" in the failure case, which is safe since we have held the folio lock. > > Acked-by: David Hildenbrand <david@xxxxxxxxxx> > Thanks.