Changeset View
Changeset View
Standalone View
Standalone View
head/emulators/xen-kernel47/files/xsa226-4.7.patch
Property | Old Value | New Value |
---|---|---|
fbsd:nokeywords | null | yes \ No newline at end of property |
svn:eol-style | null | native \ No newline at end of property |
svn:mime-type | null | text/plain \ No newline at end of property |
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: |