freebsd-ports/emulators/xen-kernel/files/xsa226-4.7.patch
Roger Pau Monné 7a08b0d624 xen-kernel: apply XSA-{226,227,228,230}
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
2017-08-15 15:08:25 +00:00

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: