From nobody Wed Sep 10 23:23:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 77809327A3A for ; Wed, 10 Sep 2025 15:34:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757518496; cv=none; b=f4NrjabjfteL9CJiO64K6H234oYnG3RiZM5m1c6FyuQSr4IgaJt9GAc63NS3SrRrjCx7un5U4JpiunUl7YGOyAM5bmvzEmUcaW34i9xSZmB8mwnw1B7WAw/FQlo0md1bJb8JRoN3odRNdZ2vpS4ANjK7lo/8MY2DU0fuAEhTJVQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757518496; c=relaxed/simple; bh=ylywEWdpuWY9ksOD7npdckXIkyDG0CoNTtEKj9xRWlw=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=tSZaLVzvPUdDe/pyzlH1cG4CBDAhtki5IaAsh+DkBxPccshOv/TM5ZRRNtqC8tXSXdFhF/QlIfuYgjllwB+wm4SrIlqmUGoFYg0OTmuuufEpoNtTDTIkZdg7E9YIRpomcGwpGdBrsKMFbzG7gru+46MAqgODHISWfZkkU3W4f5E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rhQLMmvm; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rhQLMmvm" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 557A1C4CEEB; Wed, 10 Sep 2025 15:34:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757518496; bh=ylywEWdpuWY9ksOD7npdckXIkyDG0CoNTtEKj9xRWlw=; h=From:To:Cc:Subject:Date:From; b=rhQLMmvm6dRoXeNpFCfCLVpoY7KvfC8BQX1DDVQqPnV+bvyH28j+DR3zV5mNbG15k qII2i91velnS0+nJmr0iQjTnd1tzaXScjDorFCIqvs0rH/xxjofCBUdJWiHvW4F+G6 ugswwcbJzFRZGRl2CqG1tCXrMAenb8EFyarnsSanweQl1BsoXWnzlZ/+Pac0y+5Kdl wHduKm9o9OU3V/y5/Cuv7Wh1LpDiBF7l3vJPhld6lR4lX2gTvzJhWWoTcgnVQr3dD/ SpRiF5H8Shzux16IcqivEpu60ih9iK6IJKRCPO/N1gpPtAz/wIT8YFOZ01/9O4SnXb F5ocWTAWcmZKw== From: Pratyush Yadav To: Alexander Graf , Mike Rapoport , Changyuan Lyu , Andrew Morton , Baoquan He , Pratyush Yadav , Pasha Tatashin , Jason Gunthorpe , Chris Li , Jason Miu Cc: linux-kernel@vger.kernel.org, kexec@lists.infradead.org, linux-mm@kvack.org Subject: [PATCH] kho: make sure folio being restored is actually from KHO Date: Wed, 10 Sep 2025 17:34:40 +0200 Message-ID: <20250910153443.95049-1-pratyush@kernel.org> X-Mailer: git-send-email 2.51.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When restoring a folio using kho_restore_folio(), no sanity checks are done to make sure the folio actually came from a kexec handover. The caller is trusted to pass in the right address. If the caller has a bug and passes in a wrong address, an in-use folio might be "restored" and returned, causing all sorts of memory corruption. Harden the folio restore logic by stashing in a magic number in page->private along with the folio order. If the magic number does not match, the folio won't be touched. page->private is an unsigned long. The union kho_page_info splits it into two parts, with one holding the order and the other holding the magic number. Signed-off-by: Pratyush Yadav --- kernel/kexec_handover.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c index ecd1ac210dbd7..68eb3c28abe41 100644 --- a/kernel/kexec_handover.c +++ b/kernel/kexec_handover.c @@ -32,6 +32,22 @@ #define PROP_PRESERVED_MEMORY_MAP "preserved-memory-map" #define PROP_SUB_FDT "fdt" =20 +#define KHO_PAGE_MAGIC 0x4b484f50U /* ASCII for 'KHOP' */ + +/* + * KHO uses page->private, which is an unsigned long, to store page metada= ta. + * Use it to store both the magic and the order. + */ +union kho_page_info { + unsigned long page_private; + struct { + unsigned int order; + unsigned int magic; + }; +}; + +static_assert(sizeof(union kho_page_info) =3D=3D sizeof(((struct page *)0)= ->private)); + static bool kho_enable __ro_after_init; =20 bool kho_is_enabled(void) @@ -210,16 +226,16 @@ static void kho_restore_page(struct page *page, unsig= ned int order) struct folio *kho_restore_folio(phys_addr_t phys) { struct page *page =3D pfn_to_online_page(PHYS_PFN(phys)); - unsigned long order; + union kho_page_info info; =20 if (!page) return NULL; =20 - order =3D page->private; - if (order > MAX_PAGE_ORDER) + info.page_private =3D page->private; + if (info.magic !=3D KHO_PAGE_MAGIC || info.order > MAX_PAGE_ORDER) return NULL; =20 - kho_restore_page(page, order); + kho_restore_page(page, info.order); return page_folio(page); } EXPORT_SYMBOL_GPL(kho_restore_folio); @@ -341,10 +357,13 @@ static void __init deserialize_bitmap(unsigned int or= der, phys_addr_t phys =3D elm->phys_start + (bit << (order + PAGE_SHIFT)); struct page *page =3D phys_to_page(phys); + union kho_page_info info; =20 memblock_reserve(phys, sz); memblock_reserved_mark_noinit(phys, sz); - page->private =3D order; + info.magic =3D KHO_PAGE_MAGIC; + info.order =3D order; + page->private =3D info.page_private; } } =20 base-commit: b320789d6883cc00ac78ce83bccbfe7ed58afcf0 --=20 2.47.3