• Linus Torvalds's avatar
    shmem: fix shm fallocate() list corruption · 10d20bd2
    Linus Torvalds authored
    The shmem hole punching with fallocate(FALLOC_FL_PUNCH_HOLE) does not
    want to race with generating new pages by faulting them in.
    
    However, the wait-queue used to delay the page faulting has a serious
    problem: the wait queue head (in shmem_fallocate()) is allocated on the
    stack, and the code expects that "wake_up_all()" will make sure that all
    the queue entries are gone before the stack frame is de-allocated.
    
    And that is not at all necessarily the case.
    
    Yes, a normal wake-up sequence will remove the wait-queue entry that
    caused the wakeup (see "autoremove_wake_function()"), but the key
    wording there is "that caused the wakeup".  When there are multiple
    possible wakeup sources, the wait queue entry may well stay around.
    
    And _particularly_ in a page fault path, we may be faulting in new pages
    from user space while we also have other things going on, and there may
    well be other pending wakeups.
    
    So despite the "wake_up_all()", it's not at all guaranteed that all list
    entries are removed from the wait queue head on the stack.
    
    Fix this by introducing a new wakeup function that removes the list
    entry unconditionally, even if the target process had already woken up
    for other reasons.  Use that "synchronous" function to set up the
    waiters in shmem_fault().
    
    This problem has never been seen in the wild afaik, but Dave Jones has
    reported it on and off while running trinity.  We thought we fixed the
    stack corruption with the blk-mq rq_list locking fix (commit
    7fe31130: "blk-mq: update hardware and software queues for sleeping
    alloc"), but it turns out there was _another_ stack corruptor hiding
    in the trinity runs.
    
    Vegard Nossum (also running trinity) was able to trigger this one fairly
    consistently, and made us look once again at the shmem code due to the
    faults often being in that area.
    
    Reported-and-tested-by: Vegard Nossum <vegard.nossum@oracle.com>.
    Reported-by: default avatarDave Jones <davej@codemonkey.org.uk>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    10d20bd2
shmem.c 106 KB