7a08b0d624
This is CVE-2017-12135, CVE-2017-12137, CVE-2017-12136 and CVE-2017-12855. MFH: 2017Q3 Approved by: lwshu Sponsored by: Citrix Systems R&D
133 lines
4.4 KiB
Diff
133 lines
4.4 KiB
Diff
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
|
Subject: grant_table: Default to v1, and disallow transitive grants
|
|
|
|
The reference counting and locking discipline for transitive grants is broken.
|
|
Their use is therefore declared out of security support.
|
|
|
|
This is XSA-226.
|
|
|
|
Transitive grants are expected to be unconditionally available with grant
|
|
table v2. Hiding transitive grants alone is an ABI breakage for the guest.
|
|
Modern versions of Linux and the Windows PV drivers use grant table v1, but
|
|
older versions did use v2.
|
|
|
|
In principle, disabling gnttab v2 entirely is the safer way to cause guests to
|
|
avoid using transitive grants. However, some older guests which defaulted to
|
|
using gnttab v2 don't tolerate falling back from v2 to v1 over migrate.
|
|
|
|
This patch introduces a new command line option to control grant table
|
|
behaviour. One suboption allows a choice of the maximum grant table version
|
|
Xen will allow the guest to use, and defaults to v2. A different suboption
|
|
independently controls whether transitive grants can be used.
|
|
|
|
The default case is:
|
|
|
|
gnttab=max_ver:2
|
|
|
|
To disable gnttab v2 entirely, use:
|
|
|
|
gnttab=max_ver:1
|
|
|
|
To allow gnttab v2 and transitive grants, use:
|
|
|
|
gnttab=max_ver:2,transitive
|
|
|
|
Reported-by: Jan Beulich <jbeulich@suse.com>
|
|
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
|
diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
|
|
index 73f5265..b792abf 100644
|
|
--- a/docs/misc/xen-command-line.markdown
|
|
+++ b/docs/misc/xen-command-line.markdown
|
|
@@ -758,6 +758,22 @@ Controls EPT related features.
|
|
|
|
Specify which console gdbstub should use. See **console**.
|
|
|
|
+### gnttab
|
|
+> `= List of [ max_ver:<integer>, transitive ]`
|
|
+
|
|
+> Default: `gnttab=max_ver:2,no-transitive`
|
|
+
|
|
+Control various aspects of the grant table behaviour available to guests.
|
|
+
|
|
+* `max_ver` Select the maximum grant table version to offer to guests. Valid
|
|
+version are 1 and 2.
|
|
+* `transitive` Permit or disallow the use of transitive grants. Note that the
|
|
+use of grant table v2 without transitive grants is an ABI breakage from the
|
|
+guests point of view.
|
|
+
|
|
+*Warning:*
|
|
+Due to XSA-226, the use of transitive grants is outside of security support.
|
|
+
|
|
### gnttab\_max\_frames
|
|
> `= <integer>`
|
|
|
|
diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c
|
|
index f06b664..109c552 100644
|
|
--- a/xen/common/grant_table.c
|
|
+++ b/xen/common/grant_table.c
|
|
@@ -50,6 +50,42 @@ integer_param("gnttab_max_nr_frames", max_nr_grant_frames);
|
|
unsigned int __read_mostly max_grant_frames;
|
|
integer_param("gnttab_max_frames", max_grant_frames);
|
|
|
|
+static unsigned int __read_mostly opt_gnttab_max_version = 2;
|
|
+static bool_t __read_mostly opt_transitive_grants;
|
|
+
|
|
+static void __init parse_gnttab(char *s)
|
|
+{
|
|
+ char *ss;
|
|
+
|
|
+ do {
|
|
+ ss = strchr(s, ',');
|
|
+ if ( ss )
|
|
+ *ss = '\0';
|
|
+
|
|
+ if ( !strncmp(s, "max_ver:", 8) )
|
|
+ {
|
|
+ long ver = simple_strtol(s + 8, NULL, 10);
|
|
+
|
|
+ if ( ver >= 1 && ver <= 2 )
|
|
+ opt_gnttab_max_version = ver;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ bool_t val = !!strncmp(s, "no-", 3);
|
|
+
|
|
+ if ( !val )
|
|
+ s += 3;
|
|
+
|
|
+ if ( !strcmp(s, "transitive") )
|
|
+ opt_transitive_grants = val;
|
|
+ }
|
|
+
|
|
+ s = ss + 1;
|
|
+ } while ( ss );
|
|
+}
|
|
+
|
|
+custom_param("gnttab", parse_gnttab);
|
|
+
|
|
/* The maximum number of grant mappings is defined as a multiplier of the
|
|
* maximum number of grant table entries. This defines the multiplier used.
|
|
* Pretty arbitrary. [POLICY]
|
|
@@ -2188,6 +2224,10 @@ __acquire_grant_for_copy(
|
|
}
|
|
else if ( (shah->flags & GTF_type_mask) == GTF_transitive )
|
|
{
|
|
+ if ( !opt_transitive_grants )
|
|
+ PIN_FAIL(unlock_out_clear, GNTST_general_error,
|
|
+ "transitive grant disallowed by policy\n");
|
|
+
|
|
if ( !allow_transitive )
|
|
PIN_FAIL(unlock_out_clear, GNTST_general_error,
|
|
"transitive grant when transitivity not allowed\n");
|
|
@@ -3156,7 +3196,10 @@ do_grant_table_op(
|
|
}
|
|
case GNTTABOP_set_version:
|
|
{
|
|
- rc = gnttab_set_version(guest_handle_cast(uop, gnttab_set_version_t));
|
|
+ if ( opt_gnttab_max_version == 1 )
|
|
+ rc = -ENOSYS; /* Behave as before set_version was introduced. */
|
|
+ else
|
|
+ rc = gnttab_set_version(guest_handle_cast(uop, gnttab_set_version_t));
|
|
break;
|
|
}
|
|
case GNTTABOP_get_status_frames:
|