• Siddhesh Poyarekar's avatar
    mm/fork: fix overflow in vma length when copying mmap on clone · 7edc8b0a
    Siddhesh Poyarekar authored
    The vma length in dup_mmap is calculated and stored in a unsigned int,
    which is insufficient and hence overflows for very large maps (beyond
    16TB). The following program demonstrates this:
    
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/mman.h>
    
    #define GIG 1024 * 1024 * 1024L
    #define EXTENT 16393
    
    int main(void)
    {
            int i, r;
            void *m;
            char buf[1024];
    
            for (i = 0; i < EXTENT; i++) {
                    m = mmap(NULL, (size_t) 1 * 1024 * 1024 * 1024L,
                             PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
    
                    if (m == (void *)-1)
                            printf("MMAP Failed: %d\n", m);
                    else
                            printf("%d : MMAP returned %p\n", i, m);
    
                    r = fork();
    
                    if (r == 0) {
                            printf("%d: successed\n", i);
                            return 0;
                    } else if (r < 0)
                            printf("FORK Failed: %d\n", r);
                    else if (r > 0)
                            wait(NULL);
            }
            return 0;
    }
    
    Increase the storage size of the result to unsigned long, which is
    sufficient for storing the difference between addresses.
    Signed-off-by: default avatarSiddhesh Poyarekar <siddhesh.poyarekar@gmail.com>
    Cc: Tejun Heo <tj@kernel.org>
    Cc: Oleg Nesterov <oleg@redhat.com>
    Cc: Jens Axboe <axboe@kernel.dk>
    Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Acked-by: default avatarHugh Dickins <hughd@google.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    7edc8b0a
fork.c 44.3 KB