• Ben Wolsieffer's avatar
    proc: nommu: /proc/<pid>/maps: release mmap read lock · 578d7699
    Ben Wolsieffer authored
    The no-MMU implementation of /proc/<pid>/map doesn't normally release
    the mmap read lock, because it uses !IS_ERR_OR_NULL(_vml) to determine
    whether to release the lock.  Since _vml is NULL when the end of the
    mappings is reached, the lock is not released.
    
    Reading /proc/1/maps twice doesn't cause a hang because it only
    takes the read lock, which can be taken multiple times and therefore
    doesn't show any problem if the lock isn't released. Instead, you need
    to perform some operation that attempts to take the write lock after
    reading /proc/<pid>/maps. To actually reproduce the bug, compile the
    following code as 'proc_maps_bug':
    
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/mman.h>
    
    int main(int argc, char *argv[]) {
            void *buf;
            sleep(1);
            buf = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
            puts("mmap returned");
            return 0;
    }
    
    Then, run:
    
      ./proc_maps_bug &; cat /proc/$!/maps; fg
    
    Without this patch, mmap() will hang and the command will never
    complete.
    	
    This code was incorrectly adapted from the MMU implementation, which at
    the time released the lock in m_next() before returning the last entry.
    
    The MMU implementation has diverged further from the no-MMU version since
    then, so this patch brings their locking and error handling into sync,
    fixing the bug and hopefully avoiding similar issues in the future.
    
    Link: https://lkml.kernel.org/r/20230914163019.4050530-2-ben.wolsieffer@hefring.com
    Fixes: 47fecca1 ("fs/proc/task_nommu.c: don't use priv->task->mm")
    Signed-off-by: default avatarBen Wolsieffer <ben.wolsieffer@hefring.com>
    Acked-by: default avatarOleg Nesterov <oleg@redhat.com>
    Cc: Giulio Benetti <giulio.benetti@benettiengineering.com>
    Cc: Greg Ungerer <gerg@uclinux.org>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    578d7699
task_nommu.c 6.18 KB