[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


  • To: Jan Beulich <JBeulich@xxxxxxxx>
  • From: Norbert Manthey <nmanthey@xxxxxxxxx>
  • Date: Wed, 27 Feb 2019 14:01:59 +0100
  • Autocrypt: addr=nmanthey@xxxxxxxxx; prefer-encrypt=mutual; keydata= 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 pEddsOqYwOs=
  • Cc: Juergen Gross <jgross@xxxxxxxx>, Tim Deegan <tim@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Wei Liu <wei.liu2@xxxxxxxxxx>, Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>, George Dunlap <George.Dunlap@xxxxxxxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>, Dario Faggioli <dfaggioli@xxxxxxxx>, Martin Pohlack <mpohlack@xxxxxxxxx>, wipawel@xxxxxxxxx, Julien Grall <julien.grall@xxxxxxx>, David Woodhouse <dwmw@xxxxxxxxxxxx>, "Martin Mazein\(amazein\)" <amazein@xxxxxxxxx>, xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Julian Stecklina <jsteckli@xxxxxxxxx>, Bjoern Doebel <doebel@xxxxxxxxx>
  • Delivery-date: Wed, 27 Feb 2019 13:02:26 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Openpgp: preference=signencrypt

On 2/25/19 17:46, Jan Beulich wrote:
>>>> 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.
I will change the order.
>
> 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.

So, here is the annotation for all of them. Anyone that I did not
include in the list has been fixed in previous versions, or will be
fixed in the next version:

git grep -np version common/grant_table.c

common/grant_table.c:831:static int _set_status(unsigned gt_version,
common/grant_table.c:840:    if ( gt_version == 1 )

-> I do not see how out-of-bound accesses happen in the called functions
there.

common/grant_table.c=1444=unmap_common_complete(struct
gnttab_unmap_common *op)
common/grant_table.c:1469:    if ( rgt->gt_version == 1 )

-> I do not see how to be exploitable, as the shared_entry_header call
above just used an lfence.

common/grant_table.c=1761=gnttab_grow_table(struct domain *d, unsigned
int req_nr_frames)
common/grant_table.c:1800:    /* Status pages - version 2 */
common/grant_table.c:1801:    if ( gt->gt_version > 1 )

-> I do not see how out-of-bound access could happen. This calls
gnttab_populate_status_frames that allocates pages and should not touch
more memory than before

common/grant_table.c=1904=gnttab_setup_table(
common/grant_table.c:1955:          ((gt->gt_version > 1) &&

-> I do not see how an out-of-bound access is possible.

common/grant_table.c=2104=gnttab_transfer(
common/grant_table.c:2199:            e, e->grant_table->gt_version > 1
|| paging_mode_translate(e)

-> I do not see dependent out-of-bound accesses.

common/grant_table.c=2337=release_grant_for_copy(
common/grant_table.c:2354:    if ( rgt->gt_version == 1 )
common/grant_table.c=2420=acquire_grant_for_copy(
common/grant_table.c:2452:    if ( evaluate_nospec(rgt->gt_version == 1) )
common/grant_table.c:2535:        if ( rgt->gt_version != 2 ||

-> I do not see dependent out-of-bound accesses.

common/grant_table.c=2982=static long
common/grant_table.c:2983:gnttab_set_version(XEN_GUEST_HANDLE_PARAM(gnttab_set_version_t)
uop)

-> in case of a version change, both fields are touched, and potential
out-of-bound accesses can be performed once, as the memory is allocated
afterwards and not freed during domain life time.

common/grant_table.c=3618=gnttab_release_mappings(
common/grant_table.c:3657:        if ( rgt->gt_version == 1 )

-> Is only called during domain destruction.

common/grant_table.c=3809=int mem_sharing_gref_to_gfn(struct grant_table
*gt, grant_ref_t ref,
common/grant_table.c:3817:    if ( gt->gt_version < 1 )

-> The next evaluate_nospec in the code covers the relevant memory accesses.

common/grant_table.c=3966=int gnttab_get_status_frame(struct domain *d,
unsigned long idx,
common/grant_table.c:3973:    rc = (gt->gt_version == 2) ?

-> The out-of-bound access will be blocked by using block_speculation in
gnttab_get_status_frame_mfn.

common/grant_table.c=3980=static void gnttab_usage_print(struct domain *rd)
common/grant_table.c:3994:           rd->domain_id, gt->gt_version,
common/grant_table.c:4015:        if ( gt->gt_version == 1 )

-> This function cannot be triggered by a guest.

>
> 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.

I understand that his is important for future modifications. I will
extend the commit message with the reasons when not to block speculation
wrt the version check, i.e. cannot be triggered by the guest, does not
return to the guest, does not result in an out-of-bound access or cannot
be executed repeatedly.

Best,
Norbert

> Jan
>
>




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrer: Christian Schlaeger, Ralf Herbrich
Ust-ID: DE 289 237 879
Eingetragen am Amtsgericht Charlottenburg HRB 149173 B

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.