|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH L1TF v8 9/9] common/grant_table: block speculative out-of-bound accesses
>>> On 25.02.19 at 14:34, <nmanthey@xxxxxxxxx> wrote:
> @@ -634,14 +649,24 @@ static unsigned int nr_grant_entries(struct grant_table
> *gt)
> case 1:
> BUILD_BUG_ON(f2e(INITIAL_NR_GRANT_FRAMES, 1) <
> GNTTAB_NR_RESERVED_ENTRIES);
> +
> + /* Make sure we return a value independently of speculative
> execution */
> + block_speculation();
> return f2e(nr_grant_frames(gt), 1);
> +
> case 2:
> BUILD_BUG_ON(f2e(INITIAL_NR_GRANT_FRAMES, 2) <
> GNTTAB_NR_RESERVED_ENTRIES);
> +
> + /* Make sure we return a value independently of speculative
> execution */
> + block_speculation();
> return f2e(nr_grant_frames(gt), 2);
> #undef f2e
> }
>
> + block_speculation();
> + ASSERT_UNREACHABLE();
> +
> return 0;
> }
Personally I think the assertion should be first (also in
shared_entry_header()), but that's nothing very important to
change.
Below here, but before the next patch hunk, is _set_status(). If
you think there's no need to change its gt_version check, then I
think the commit message should (briefly) explain this.
> @@ -1418,7 +1450,7 @@ unmap_common_complete(struct gnttab_unmap_common *op)
> struct page_info *pg;
> uint16_t *status;
>
> - if ( !op->done )
> + if ( evaluate_nospec(!op->done) )
> {
> /* unmap_common() didn't do anything - nothing to complete. */
> return;
Just like above, below here (in the same function) is another version
check you don't adjust, and there are further ones in gnttab_grow_table(),
gnttab_setup_table(), and release_grant_for_copy().
> @@ -2408,9 +2445,11 @@ acquire_grant_for_copy(
> PIN_FAIL(gt_unlock_out, GNTST_bad_gntref,
> "Bad grant reference %#x\n", gref);
>
> - act = active_entry_acquire(rgt, gref);
> + /* This call ensures the above check cannot be bypassed speculatively */
> shah = shared_entry_header(rgt, gref);
> - if ( rgt->gt_version == 1 )
> + act = active_entry_acquire(rgt, gref);
> +
> + if ( evaluate_nospec(rgt->gt_version == 1) )
> {
> sha2 = NULL;
> status = &shah->flags;
There's again a second version check further down in this function.
> @@ -2945,7 +2987,7 @@
> gnttab_set_version(XEN_GUEST_HANDLE_PARAM(gnttab_set_version_t) uop)
> struct grant_table *gt = currd->grant_table;
> grant_entry_v1_t reserved_entries[GNTTAB_NR_RESERVED_ENTRIES];
> int res;
> - unsigned int i;
> + unsigned int i, nr_ents;
>
> if ( copy_from_guest(&op, uop, 1) )
> return -EFAULT;
> @@ -2969,7 +3011,8 @@
> gnttab_set_version(XEN_GUEST_HANDLE_PARAM(gnttab_set_version_t) uop)
> * are allowed to be in use (xenstore/xenconsole keeps them mapped).
> * (You need to change the version number for e.g. kexec.)
> */
> - for ( i = GNTTAB_NR_RESERVED_ENTRIES; i < nr_grant_entries(gt); i++ )
> + nr_ents = nr_grant_entries(gt);
> + for ( i = GNTTAB_NR_RESERVED_ENTRIES; i < nr_ents; i++ )
> {
> if ( read_atomic(&_active_entry(gt, i).pin) != 0 )
> {
What about the various version accesses in this function? And
while I think the one in gnttab_release_mappings() doesn't need
adjustment, it should (also) be mentioned in the description. The
one in gnttab_map_frame(9, otoh, looks as if it again needed
adjustment.
I would really like to ask that I (or someone else) don't need to
go through and list remaining version checks again - after all I
had done so for v6 already, and I didn't go through all of them
again for v7 assuming that you would have worked through the
entire set.
Mentioning reasons of omitted adjustments is in particular
important for people to have a reference down the road, to be
able to tell whether new version checks to add need to take one
shape or the other.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |