• Hugh Dickins's avatar
    shmem: fix faulting into a hole, not taking i_mutex · 8e205f77
    Hugh Dickins authored
    Commit f00cdc6d ("shmem: fix faulting into a hole while it's
    punched") was buggy: Sasha sent a lockdep report to remind us that
    grabbing i_mutex in the fault path is a no-no (write syscall may already
    hold i_mutex while faulting user buffer).
    
    We tried a completely different approach (see following patch) but that
    proved inadequate: good enough for a rational workload, but not good
    enough against trinity - which forks off so many mappings of the object
    that contention on i_mmap_mutex while hole-puncher holds i_mutex builds
    into serious starvation when concurrent faults force the puncher to fall
    back to single-page unmap_mapping_range() searches of the i_mmap tree.
    
    So return to the original umbrella approach, but keep away from i_mutex
    this time.  We really don't want to bloat every shmem inode with a new
    mutex or completion, just to protect this unlikely case from trinity.
    So extend the original with wait_queue_head on stack at the hole-punch
    end, and wait_queue item on the stack at the fault end.
    
    This involves further use of i_lock to guard against the races: lockdep
    has been happy so far, and I see fs/inode.c:unlock_new_inode() holds
    i_lock around wake_up_bit(), which is comparable to what we do here.
    i_lock is more convenient, but we could switch to shmem's info->lock.
    
    This issue has been tagged with CVE-2014-4171, which will require commit
    f00cdc6d and this and the following patch to be backported: we
    suggest to 3.1+, though in fact the trinity forkbomb effect might go
    back as far as 2.6.16, when madvise(,,MADV_REMOVE) came in - or might
    not, since much has changed, with i_mmap_mutex a spinlock before 3.0.
    Anyone running trinity on 3.0 and earlier? I don't think we need care.
    Signed-off-by: default avatarHugh Dickins <hughd@google.com>
    Reported-by: default avatarSasha Levin <sasha.levin@oracle.com>
    Tested-by: default avatarSasha Levin <sasha.levin@oracle.com>
    Cc: Vlastimil Babka <vbabka@suse.cz>
    Cc: Konstantin Khlebnikov <koct9i@gmail.com>
    Cc: Johannes Weiner <hannes@cmpxchg.org>
    Cc: Lukas Czerner <lczerner@redhat.com>
    Cc: Dave Jones <davej@redhat.com>
    Cc: <stable@vger.kernel.org>	[3.1+]
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    8e205f77
shmem.c 79.3 KB