From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from canpmsgout07.his.huawei.com (canpmsgout07.his.huawei.com [113.46.200.222]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9D69A422540 for ; Tue, 25 Aug 2026 12:21:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.222 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787660499; cv=none; b=mpAkAUPcImQ83Xs1pQrvP/hyGrC+3zM+ImJDkcpDp6DIge7WYuDhkuNrd5DQJRQxLcvL/U2Xf+dJwPc5cJ/5RPHd0MtnyiY5WaBr6VBF5dH6dnyjnJ9ikm8RFMA/QCgiGdvnESsc9Rf1/ILZsFfpknZ65zw9ha54nM7XG9Q+o5o= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787660499; c=relaxed/simple; bh=jK432yXijioQoBZ2vNiTkaJSO9u67D3xA8SNt0u95XY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ii/YgZBm4LxlqNAePdn0JZ0bQaJpfMCnfkaHpiBJv9nGT2W0VCfh2TDhS36oi9f8AbtxGS/IQ5pVOSAa5nbskNNDjWBIdLKCemeQSWj10dQ3CrNa3aSJ70rhJMBry1AkA42eVET4wpCkOkQEGU2b16iqi7umMvWBxE0SyFrAeI8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=QojxQPHB; arc=none smtp.client-ip=113.46.200.222 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="QojxQPHB" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=ZT765UJFYyMTJoOY408mF7kpDLgZOjbYjc0ctgYvIGo=; b=QojxQPHB6N8tDMeJFSG82r1iHX1BVlZHZrbQSWRiFspic1EIA+RwZ0FC0jGJskGYu5RmgraAv c65bZaRMxp4ipe8VBMIWIkUjlkCaDKLeFIEvCiXFpRgJIqA0s5pxfkPvUyTWbTdfomQ63LlmQhd k+uB+ArmyiEZPXYoTpz7CEs= Received: from mail.maildlp.com (unknown [172.19.163.214]) by canpmsgout07.his.huawei.com (SkyGuard) with ESMTPS id 4hTmnr5Xj8zLlTk; Tue, 25 Aug 2026 20:10:40 +0800 (CST) Received: from kwepemo200010.china.huawei.com (unknown [7.202.195.178]) by mail.maildlp.com (Postfix) with ESMTPS id D27664056C; Tue, 25 Aug 2026 20:21:25 +0800 (CST) Received: from huawei.com (10.44.142.85) by kwepemo200010.china.huawei.com (7.202.195.178) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.45; Tue, 25 Aug 2026 20:21:25 +0800 From: Qi Xi To: Andrew Morton , Vlastimil Babka CC: Suren Baghdasaryan , Michal Hocko , Brendan Jackman , Johannes Weiner , Zi Yan , , , , , Subject: [PATCH v3 2/2] mm/page_isolation: guard compound_order() against racing Date: Tue, 25 Aug 2026 20:05:49 +0800 Message-ID: <20260825120549.966271-3-xiqi2@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260825120549.966271-1-xiqi2@huawei.com> References: <20260825120549.966271-1-xiqi2@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: kwepems200001.china.huawei.com (7.221.188.67) To kwepemo200010.china.huawei.com (7.202.195.178) The PageCompound branch reads compound_head() without holding a reference. A racing split or free can cause compound_head() to return a stale pointer, and compound_nr() reads the order from that stale head, leading to out-of-range shifts and making the skip distance meaningless. Read the order explicitly with compound_order() and validate it is within MAX_FOLIO_ORDER before shifting. Also verify the derived head_pfn against the legitimate pfn: the head must not be past pfn, must be aligned to nr_pages, and pfn must fall within the compound page. Bail out with -EBUSY if any check fails. Fixes: b2c9e2fbba32 ("mm: make alloc_contig_range work at pageblock granularity") Cc: stable@vger.kernel.org Suggested-by: Zi Yan Reviewed-by: Zi Yan Signed-off-by: Qi Xi --- mm/page_isolation.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/mm/page_isolation.c b/mm/page_isolation.c index 61efc03500ef..eca6fb78f73a 100644 --- a/mm/page_isolation.c +++ b/mm/page_isolation.c @@ -418,10 +418,28 @@ static int isolate_single_pageblock(unsigned long boundary_pfn, if (PageCompound(page)) { struct page *head = compound_head(page); unsigned long head_pfn = page_to_pfn(head); - unsigned long nr_pages = compound_nr(head); + unsigned int order = compound_order(head); + unsigned long nr_pages; + + /* compound_order() is racy. Cap it at MAX_FOLIO_ORDER. */ + if (order > MAX_FOLIO_ORDER) + goto failed; + + nr_pages = 1UL << order; + + /* + * compound_head() is also racy, so the derived head_pfn + * needs additional checks to make sure it is valid. + * Otherwise, just fail the check. pfn comes from + * __first_valid_page() as a legitimate PFN, so use it to + * check head_pfn. + */ + if (head_pfn > pfn || !IS_ALIGNED(head_pfn, nr_pages) || + pfn - head_pfn >= nr_pages) + goto failed; if (head_pfn + nr_pages <= boundary_pfn || - PageHuge(page)) { + PageHuge(head)) { pfn = head_pfn + nr_pages; continue; } -- 2.33.0