• Matthew Wilcox (Oracle)'s avatar
    XArray: Disallow sibling entries of nodes · 63b1898f
    Matthew Wilcox (Oracle) authored
    There is a race between xas_split() and xas_load() which can result in
    the wrong page being returned, and thus data corruption.  Fortunately,
    it's hard to hit (syzbot took three months to find it) and often guarded
    with VM_BUG_ON().
    
    The anatomy of this race is:
    
    thread A			thread B
    order-9 page is stored at index 0x200
    				lookup of page at index 0x274
    page split starts
    				load of sibling entry at offset 9
    stores nodes at offsets 8-15
    				load of entry at offset 8
    
    The entry at offset 8 turns out to be a node, and so we descend into it,
    and load the page at index 0x234 instead of 0x274.  This is hard to fix
    on the split side; we could replace the entire node that contains the
    order-9 page instead of replacing the eight entries.  Fixing it on
    the lookup side is easier; just disallow sibling entries that point
    to nodes.  This cannot ever be a useful thing as the descent would not
    know the correct offset to use within the new node.
    
    The test suite continues to pass, but I have not added a new test for
    this bug.
    
    Reported-by: syzbot+cf4cf13056f85dec2c40@syzkaller.appspotmail.com
    Tested-by: syzbot+cf4cf13056f85dec2c40@syzkaller.appspotmail.com
    Fixes: 6b24ca4a ("mm: Use multi-index entries in the page cache")
    Signed-off-by: default avatarMatthew Wilcox (Oracle) <willy@infradead.org>
    63b1898f
xarray.c 58.8 KB