gnttab: never permit mapping transitive grants
authorJan Beulich <jbeulich@suse.com>
Thu, 18 Feb 2021 12:16:12 +0000 (13:16 +0100)
committerJan Beulich <jbeulich@suse.com>
Thu, 18 Feb 2021 12:16:12 +0000 (13:16 +0100)
commitb339e3a976b1680f57051adabcb98281198f7eac
tree449cc83f93bf9786cf208e7f0dcd0b6c8e7af8b6
parent588d961d15d1af5b51d7c33b5278ac7269a961ef
gnttab: never permit mapping transitive grants

Transitive grants allow an intermediate domain I to grant a target
domain T access to a page which origin domain O did grant I access to.
As an implementation restriction, T is not allowed to map such a grant.
This restriction is currently tried to be enforced by marking active
entries resulting from transitive grants as is-sub-page; sub-page grants
for obvious reasons don't allow mapping. However, marking (and checking)
only active entries is insufficient, as a map attempt may also occur on
a grant not otherwise in use. When not presently in use (pin count zero)
the grant type itself needs checking. Otherwise T may be able to map an
unrelated page owned by I. This is because the "transitive" sub-
structure of the v2 union would end up being interpreted as "full_page"
sub-structure instead. The low 32 bits of the GFN used would match the
grant reference specified in I's transitive grant entry, while the upper
32 bits could be random (depending on how exactly I sets up its grant
table entries).

Note that if one mapping already exists and the granting domain _then_
changes the grant to GTF_transitive (which the domain is not supposed to
do), the changed type will only be honored after the pin count has gone
back to zero. This is no different from e.g. GTF_readonly or
GTF_sub_page becoming set when a grant is already in use.

While adjusting the implementation, also adjust commentary in the public
header to better reflect reality.

Fixes: 3672ce675c93 ("Transitive grant support")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Julien Grall <jgrall@amazon.com>
xen/common/grant_table.c
xen/include/public/grant_table.h