summaryrefslogtreecommitdiff
path: root/system/xen/xsa/xsa226.patch
diff options
context:
space:
mode:
Diffstat (limited to 'system/xen/xsa/xsa226.patch')
-rw-r--r--system/xen/xsa/xsa226.patch133
1 files changed, 133 insertions, 0 deletions
diff --git a/system/xen/xsa/xsa226.patch b/system/xen/xsa/xsa226.patch
new file mode 100644
index 0000000000..48fae12172
--- /dev/null
+++ b/system/xen/xsa/xsa226.patch
@@ -0,0 +1,133 @@
+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 4002eab..af079b4 100644
+--- a/docs/misc/xen-command-line.markdown
++++ b/docs/misc/xen-command-line.markdown
+@@ -868,6 +868,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 ae34547..87131f8 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 __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 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]
+@@ -2191,6 +2227,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");
+@@ -3159,7 +3199,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: