diff options
Diffstat (limited to 'system/xen/xsa/xsa226.patch')
-rw-r--r-- | system/xen/xsa/xsa226.patch | 133 |
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: |