stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org,
	Simon Gaiser <simon@invisiblethingslab.com>,
	Juergen Gross <jgross@suse.com>, Jan Beulich <jbeulich@suse.com>
Subject: [PATCH 5.4 31/33] xen/gnttab: fix gnttab_end_foreign_access() without page specified
Date: Thu, 10 Mar 2022 15:19:32 +0100	[thread overview]
Message-ID: <20220310140809.655025121@linuxfoundation.org> (raw)
In-Reply-To: <20220310140808.741682643@linuxfoundation.org>

From: Juergen Gross <jgross@suse.com>

Commit 42baefac638f06314298087394b982ead9ec444b upstream.

gnttab_end_foreign_access() is used to free a grant reference and
optionally to free the associated page. In case the grant is still in
use by the other side processing is being deferred. This leads to a
problem in case no page to be freed is specified by the caller: the
caller doesn't know that the page is still mapped by the other side
and thus should not be used for other purposes.

The correct way to handle this situation is to take an additional
reference to the granted page in case handling is being deferred and
to drop that reference when the grant reference could be freed
finally.

This requires that there are no users of gnttab_end_foreign_access()
left directly repurposing the granted page after the call, as this
might result in clobbered data or information leaks via the not yet
freed grant reference.

This is part of CVE-2022-23041 / XSA-396.

Reported-by: Simon Gaiser <simon@invisiblethingslab.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/xen/grant-table.c |   36 +++++++++++++++++++++++++++++-------
 include/xen/grant_table.h |    7 ++++++-
 2 files changed, 35 insertions(+), 8 deletions(-)

--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -134,6 +134,10 @@ struct gnttab_ops {
 	 * return the frame.
 	 */
 	unsigned long (*end_foreign_transfer_ref)(grant_ref_t ref);
+	/*
+	 * Read the frame number related to a given grant reference.
+	 */
+	unsigned long (*read_frame)(grant_ref_t ref);
 };
 
 struct unmap_refs_callback_data {
@@ -331,6 +335,16 @@ int gnttab_end_foreign_access_ref(grant_
 }
 EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref);
 
+static unsigned long gnttab_read_frame_v1(grant_ref_t ref)
+{
+	return gnttab_shared.v1[ref].frame;
+}
+
+static unsigned long gnttab_read_frame_v2(grant_ref_t ref)
+{
+	return gnttab_shared.v2[ref].full_page.frame;
+}
+
 struct deferred_entry {
 	struct list_head list;
 	grant_ref_t ref;
@@ -360,12 +374,9 @@ static void gnttab_handle_deferred(struc
 		spin_unlock_irqrestore(&gnttab_list_lock, flags);
 		if (_gnttab_end_foreign_access_ref(entry->ref, entry->ro)) {
 			put_free_entry(entry->ref);
-			if (entry->page) {
-				pr_debug("freeing g.e. %#x (pfn %#lx)\n",
-					 entry->ref, page_to_pfn(entry->page));
-				put_page(entry->page);
-			} else
-				pr_info("freeing g.e. %#x\n", entry->ref);
+			pr_debug("freeing g.e. %#x (pfn %#lx)\n",
+				 entry->ref, page_to_pfn(entry->page));
+			put_page(entry->page);
 			kfree(entry);
 			entry = NULL;
 		} else {
@@ -390,9 +401,18 @@ static void gnttab_handle_deferred(struc
 static void gnttab_add_deferred(grant_ref_t ref, bool readonly,
 				struct page *page)
 {
-	struct deferred_entry *entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
+	struct deferred_entry *entry;
+	gfp_t gfp = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL;
 	const char *what = KERN_WARNING "leaking";
 
+	entry = kmalloc(sizeof(*entry), gfp);
+	if (!page) {
+		unsigned long gfn = gnttab_interface->read_frame(ref);
+
+		page = pfn_to_page(gfn_to_pfn(gfn));
+		get_page(page);
+	}
+
 	if (entry) {
 		unsigned long flags;
 
@@ -1284,6 +1304,7 @@ static const struct gnttab_ops gnttab_v1
 	.update_entry			= gnttab_update_entry_v1,
 	.end_foreign_access_ref		= gnttab_end_foreign_access_ref_v1,
 	.end_foreign_transfer_ref	= gnttab_end_foreign_transfer_ref_v1,
+	.read_frame			= gnttab_read_frame_v1,
 };
 
 static const struct gnttab_ops gnttab_v2_ops = {
@@ -1295,6 +1316,7 @@ static const struct gnttab_ops gnttab_v2
 	.update_entry			= gnttab_update_entry_v2,
 	.end_foreign_access_ref		= gnttab_end_foreign_access_ref_v2,
 	.end_foreign_transfer_ref	= gnttab_end_foreign_transfer_ref_v2,
+	.read_frame			= gnttab_read_frame_v2,
 };
 
 static bool gnttab_need_v2(void)
--- a/include/xen/grant_table.h
+++ b/include/xen/grant_table.h
@@ -100,7 +100,12 @@ int gnttab_end_foreign_access_ref(grant_
  * Note that the granted page might still be accessed (read or write) by the
  * other side after gnttab_end_foreign_access() returns, so even if page was
  * specified as 0 it is not allowed to just reuse the page for other
- * purposes immediately.
+ * purposes immediately. gnttab_end_foreign_access() will take an additional
+ * reference to the granted page in this case, which is dropped only after
+ * the grant is no longer in use.
+ * This requires that multi page allocations for areas subject to
+ * gnttab_end_foreign_access() are done via alloc_pages_exact() (and freeing
+ * via free_pages_exact()) in order to avoid high order pages.
  */
 void gnttab_end_foreign_access(grant_ref_t ref, int readonly,
 			       unsigned long page);



  parent reply	other threads:[~2022-03-10 14:33 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-10 14:19 [PATCH 5.4 00/33] 5.4.184-rc2 review Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 01/33] x86/speculation: Merge one test in spectre_v2_user_select_mitigation() Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 02/33] x86,bugs: Unconditionally allow spectre_v2=retpoline,amd Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 03/33] x86/speculation: Rename RETPOLINE_AMD to RETPOLINE_LFENCE Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 04/33] x86/speculation: Add eIBRS + Retpoline options Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 05/33] Documentation/hw-vuln: Update spectre doc Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 06/33] x86/speculation: Include unprivileged eBPF status in Spectre v2 mitigation reporting Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 07/33] x86/speculation: Use generic retpoline by default on AMD Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 08/33] x86/speculation: Update link to AMD speculation whitepaper Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 09/33] x86/speculation: Warn about Spectre v2 LFENCE mitigation Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 10/33] x86/speculation: Warn about eIBRS + LFENCE + Unprivileged eBPF + SMT Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 11/33] arm/arm64: Provide a wrapper for SMCCC 1.1 calls Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 12/33] arm/arm64: smccc/psci: add arm_smccc_1_1_get_conduit() Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 13/33] ARM: report Spectre v2 status through sysfs Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 14/33] ARM: early traps initialisation Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 15/33] ARM: use LOADADDR() to get load address of sections Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 16/33] ARM: Spectre-BHB workaround Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 17/33] ARM: include unprivileged BPF status in Spectre V2 reporting Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 18/33] ARM: fix build error when BPF_SYSCALL is disabled Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 19/33] ARM: fix co-processor register typo Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 20/33] ARM: Do not use NOCROSSREFS directive with ld.lld Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 21/33] ARM: fix build warning in proc-v7-bugs.c Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 22/33] xen/xenbus: dont let xenbus_grant_ring() remove grants in error case Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 23/33] xen/grant-table: add gnttab_try_end_foreign_access() Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 24/33] xen/blkfront: dont use gnttab_query_foreign_access() for mapped status Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 25/33] xen/netfront: " Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 26/33] xen/scsifront: " Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 27/33] xen/gntalloc: dont use gnttab_query_foreign_access() Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 28/33] xen: remove gnttab_query_foreign_access() Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 29/33] xen/9p: use alloc/free_pages_exact() Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 30/33] xen/pvcalls: " Greg Kroah-Hartman
2022-03-10 14:19 ` Greg Kroah-Hartman [this message]
2022-03-10 14:19 ` [PATCH 5.4 32/33] xen/netfront: react properly to failing gnttab_end_foreign_access_ref() Greg Kroah-Hartman
2022-03-10 14:19 ` [PATCH 5.4 33/33] Revert "ACPI: PM: s2idle: Cancel wakeup before dispatching EC GPE" Greg Kroah-Hartman
2022-03-10 18:48 ` [PATCH 5.4 00/33] 5.4.184-rc2 review Jon Hunter
2022-03-10 19:33 ` Shuah Khan
2022-03-10 22:11 ` Florian Fainelli
2022-03-11  1:02 ` Guenter Roeck
2022-03-11  9:58 ` Sudip Mukherjee
2022-03-11 12:14 ` Naresh Kamboju

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220310140809.655025121@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=jbeulich@suse.com \
    --cc=jgross@suse.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=simon@invisiblethingslab.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).