[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen staging-4.15] gnttab: avoid triggering assertion in radix_tree_ulong_to_ptr()



commit e58edae768bff17e1af652e3fae716c29b14c6e4
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Wed Sep 8 14:45:18 2021 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed Sep 8 14:45:18 2021 +0200

    gnttab: avoid triggering assertion in radix_tree_ulong_to_ptr()
    
    Relevant quotes from the C11 standard:
    
    "Except where explicitly stated otherwise, for the purposes of this
     subclause unnamed members of objects of structure and union type do not
     participate in initialization. Unnamed members of structure objects
     have indeterminate value even after initialization."
    
    "If there are fewer initializers in a brace-enclosed list than there are
     elements or members of an aggregate, [...], the remainder of the
     aggregate shall be initialized implicitly the same as objects that have
     static storage duration."
    
    "If an object that has static or thread storage duration is not
     initialized explicitly, then:
     [...]
     â?? if it is an aggregate, every member is initialized (recursively)
       according to these rules, and any padding is initialized to zero
       bits;
     [...]"
    
    "A bit-field declaration with no declarator, but only a colon and a
     width, indicates an unnamed bit-field." Footnote: "An unnamed bit-field
     structure member is useful for padding to conform to externally imposed
     layouts."
    
    "There may be unnamed padding within a structure object, but not at its
     beginning."
    
    Which makes me conclude:
    - Whether an unnamed bit-field member is an unnamed member or padding is
      unclear, and hence also whether the last quote above would render the
      big endian case of the structure declaration invalid.
    - Whether the number of members of an aggregate includes unnamed ones is
      also not really clear.
    - The initializer in map_grant_ref() initializes all fields of the "cnt"
      sub-structure of the union, so assuming the second quote above applies
      here (indirectly), the compiler isn't required to implicitly
      initialize the rest (i.e. in particular any padding) like would happen
      for static storage duration objects.
    
    Gcc 7.4.1 can be observed (apparently in debug builds only) to translate
    aforementioned initializer to a read-modify-write operation of a stack
    variable, leaving unchanged the top two bits of whatever was previously
    in that stack slot. Clearly if either of the two bits were set,
    radix_tree_ulong_to_ptr()'s assertion would trigger.
    
    Therefore, to be on the safe side, add an explicit padding field for the
    non-big-endian-bitfields case and give a dummy name to both padding
    fields.
    
    Fixes: 9781b51efde2 ("gnttab: replace mapkind()")
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    master commit: b6da9d0414d69c2682214ee3ecf9816fcac500d0
    master date: 2021-08-27 10:54:46 +0200
---
 xen/common/grant_table.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c
index d3f8dc8c4d..fd66863abc 100644
--- a/xen/common/grant_table.c
+++ b/xen/common/grant_table.c
@@ -964,10 +964,13 @@ union maptrack_node {
     struct {
         /* Radix tree slot pointers use two of the bits. */
 #ifdef __BIG_ENDIAN_BITFIELD
-        unsigned long    : 2;
+        unsigned long _0 : 2;
 #endif
         unsigned long rd : BITS_PER_LONG / 2 - 1;
         unsigned long wr : BITS_PER_LONG / 2 - 1;
+#ifndef __BIG_ENDIAN_BITFIELD
+        unsigned long _0 : 2;
+#endif
     } cnt;
     unsigned long raw;
 };
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.15



 


Rackspace

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