Xen Security Advisory 300 v1 - Linux: No grant table and foreign mapping limits

Xen.org security team <[email protected]>
Newsgroups gmane.comp.emulators.xen.announce
Message-ID <E1hkqb8-0005kj-Mn__12672.9109136917$1562680899$gmane$org@xenbits.xenproject.org>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

                    Xen Security Advisory XSA-300

             Linux: No grant table and foreign mapping limits

ISSUE DESCRIPTION
=================

Virtual device backends and device models running in domain 0, or
other backend driver domains, need to be able to map guest memory
(either via grant mappings, or via the foreign mapping interface).
For Linux to keep track of these mappings, it needs to have a page
structure for each one.  In practice the number of page structures is
usually limited.  In PV dom0, a range of pfns are typically set aside
at boot ("pre-ballooned") for this purpose; for PVH and Arm dom0s, no
memory is set aside to begin with.  In either case, when more of this
"foreign / grant map pfn space" is needed, dom0 will balloon out extra
pages to use for this purpose.

Unfortunately, in Linux, there are no limits, either on the total
amount of memory which dom0 will attempt to balloon down to, nor on
the amount of "foreign / grant map" memory which any individual guest
can consume.

As a result, a malicious guest may be able, with crafted requests to
the backend, to cause dom0 to exhaust its own memory, leading to a
host crash; and if this is not possible, it may be able to monopolize
all of the foreign / grant map pfn space, starving out other guests.

IMPACT
======

Guest may be able to crash domain 0 (Host Denial-of-Service); or may
be able to starve out I/O requests from other guests (Guest
Denial-of-Service).

VULNERABLE SYSTEMS
==================

All versions of Linux are vulnerable.

All Arm dom0s are vulnerable; on x86, PVH dom0 is generally vulnerable,
while PV dom0's vulnerability depends on what, if any, "dom0_mem="
option was passed to Xen.

MITIGATION
==========

On PV dom0, the amount of "pre-ballooned" memory can be increased by
limiting dom0 memory via "dom0_mem=", but avoiding use of the
"dom0_mem=max:<value>" form of the command line option, or by making
the delta between "actual" and "maximum" sufficiently large.  This makes
the attack more difficult to accomplish.

CREDITS
=======

This issue was discovered by Julien Grall of ARM.

RESOLUTION
==========

Applying the appropriate attached patch resolves the domain 0 memory
exhaustion issue.

NOTE: This does NOT fix the guest starvation issue.  Fixing fixing
this issue is more complex, and it was determined that it was better
to work on a robust fix for the issue in public.  This advisory will
be updated when fixes are available.

xsa300-linux-5.1.patch     Linux 4.4 ... 5.2-rc

$ sha256sum xsa300*
9c8a9aec52b147f8e8ef41444e1dd11803bacf3bd4d0f6efa863b16f7a9621ac  xsa300-linux-5.1.patch
$

NOTE ON LACK OF EMBARGO
=======================

The lack of predisclosure is due to a short schedule set by the
discoverer, and efforts to resolve the advisory wording.

DEPLOYMENT DURING EMBARGO
=========================

Deployment of the patches and/or mitigations described above (or
others which are substantially similar) is permitted during the
embargo, even on public-facing systems with untrusted guest users and
administrators.

But: Distribution of updated software is prohibited (except to other
members of the predisclosure list).

Predisclosure list members who wish to deploy significantly different
patches and/or mitigations, please contact the Xen Project Security
Team.


(Note: this during-embargo deployment notice is retained in
post-embargo publicly released Xen Project advisories, even though it
is then no longer applicable.  This is to enable the community to have
oversight of the Xen Project Security Team's decisionmaking.)

For more information about permissible uses of embargoed information,
consult the Xen Project community's agreed Security Policy:
  http://www.xenproject.org/security-policy.html
-----BEGIN PGP SIGNATURE-----

iQFABAEBCAAqFiEEI+MiLBRfRHX6gGCng/4UyVfoK9kFAl0knK4MHHBncEB4ZW4u
b3JnAAoJEIP+FMlX6CvZVp0H/2P+7XAtIAS2owhUnTBPSmM/93LZBHr67DCGSoix
afHEumj4b3omIssAEo912BXpG0tjzCBlStwacRDc/11Ku4XtB/hlr5TG89c2tfVd
QMtvWeAdDjWE2YkwZ3TK5BgaYMwoUSMdwXtG2NGpVGFj4jy4AUL5e+sZKAiMTbl2
f3ursyyts/cgJTLq1KHfX3jVlqcRLvv0yGXLsZ0BQbktnEpptETPPtBvEQQ+Uqkb
WjqxCvzmh0Szc9mnhLSxS2LDA6W/y/r37XawpwJIZNpE12+sQRZ48KqeFysTK4Yp
MRZokgzOBOXfHVa25LpgtZzL5DmRR5AfWYkmgmIX8s7NaH8=
=OKdx
-----END PGP SIGNATURE-----

_______________________________________________
Xen-announce mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-announce
xsa300-linux-5.1.patch (application/octet-stream, 2.2 KB)
From ea49450ded575facc0e64e0d6adcb1ca8aaad0ba Mon Sep 17 00:00:00 2001
From: Juergen Gross <[email protected]>
Date: Wed, 19 Jun 2019 11:00:56 +0200
Subject: [PATCH] xen: let alloc_xenballooned_pages() fail if not enough memory
 free

Instead of trying to allocate pages with GFP_USER in
add_ballooned_pages() check the available free memory via
si_mem_available(). GFP_USER is far less limiting memory exhaustion
than the test via si_mem_available().

This will avoid dom0 running out of memory due to excessive foreign
page mappings especially on ARM and on x86 in PVH mode, as those don't
have a pre-ballooned area which can be used for foreign mappings.

As the normal ballooning suffers from the same problem don't balloon
down more than si_mem_available() pages in one iteration. At the same
time limit the default maximum number of retries.

Reported-by: Julien Grall <[email protected]>
Signed-off-by: Juergen Gross <[email protected]>
---
 drivers/xen/balloon.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index d37dd5bb7a8f..559768dc2567 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -538,8 +538,15 @@ static void balloon_process(struct work_struct *work)
 				state = reserve_additional_memory();
 		}
 
-		if (credit < 0)
-			state = decrease_reservation(-credit, GFP_BALLOON);
+		if (credit < 0) {
+			long n_pages;
+
+			n_pages = min(-credit, si_mem_available());
+			state = decrease_reservation(n_pages, GFP_BALLOON);
+			if (state == BP_DONE && n_pages != -credit &&
+			    n_pages < totalreserve_pages)
+				state = BP_EAGAIN;
+		}
 
 		state = update_schedule(state);
 
@@ -578,6 +585,9 @@ static int add_ballooned_pages(int nr_pages)
 		}
 	}
 
+	if (si_mem_available() < nr_pages)
+		return -ENOMEM;
+
 	st = decrease_reservation(nr_pages, GFP_USER);
 	if (st != BP_DONE)
 		return -ENOMEM;
@@ -710,7 +720,7 @@ static int __init balloon_init(void)
 	balloon_stats.schedule_delay = 1;
 	balloon_stats.max_schedule_delay = 32;
 	balloon_stats.retry_count = 1;
-	balloon_stats.max_retry_count = RETRY_UNLIMITED;
+	balloon_stats.max_retry_count = 4;
 
 #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
 	set_online_page_callback(&xen_online_page);
-- 
2.16.4
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.