]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.4.2/mm-fork-fix-overflow-in-vma-length-when-copying-mmap-on-clone.patch
Linux 4.14.95
[thirdparty/kernel/stable-queue.git] / releases / 3.4.2 / mm-fork-fix-overflow-in-vma-length-when-copying-mmap-on-clone.patch
1 From 7edc8b0ac16cbaed7cb4ea4c6b95ce98d2997e84 Mon Sep 17 00:00:00 2001
2 From: Siddhesh Poyarekar <siddhesh.poyarekar@gmail.com>
3 Date: Tue, 29 May 2012 15:06:22 -0700
4 Subject: mm/fork: fix overflow in vma length when copying mmap on clone
5
6 From: Siddhesh Poyarekar <siddhesh.poyarekar@gmail.com>
7
8 commit 7edc8b0ac16cbaed7cb4ea4c6b95ce98d2997e84 upstream.
9
10 The vma length in dup_mmap is calculated and stored in a unsigned int,
11 which is insufficient and hence overflows for very large maps (beyond
12 16TB). The following program demonstrates this:
13
14 #include <stdio.h>
15 #include <unistd.h>
16 #include <sys/mman.h>
17
18 #define GIG 1024 * 1024 * 1024L
19 #define EXTENT 16393
20
21 int main(void)
22 {
23 int i, r;
24 void *m;
25 char buf[1024];
26
27 for (i = 0; i < EXTENT; i++) {
28 m = mmap(NULL, (size_t) 1 * 1024 * 1024 * 1024L,
29 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
30
31 if (m == (void *)-1)
32 printf("MMAP Failed: %d\n", m);
33 else
34 printf("%d : MMAP returned %p\n", i, m);
35
36 r = fork();
37
38 if (r == 0) {
39 printf("%d: successed\n", i);
40 return 0;
41 } else if (r < 0)
42 printf("FORK Failed: %d\n", r);
43 else if (r > 0)
44 wait(NULL);
45 }
46 return 0;
47 }
48
49 Increase the storage size of the result to unsigned long, which is
50 sufficient for storing the difference between addresses.
51
52 Signed-off-by: Siddhesh Poyarekar <siddhesh.poyarekar@gmail.com>
53 Cc: Tejun Heo <tj@kernel.org>
54 Cc: Oleg Nesterov <oleg@redhat.com>
55 Cc: Jens Axboe <axboe@kernel.dk>
56 Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
57 Acked-by: Hugh Dickins <hughd@google.com>
58 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
59 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
60 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
61
62 ---
63 kernel/fork.c | 3 ++-
64 1 file changed, 2 insertions(+), 1 deletion(-)
65
66 --- a/kernel/fork.c
67 +++ b/kernel/fork.c
68 @@ -356,7 +356,8 @@ static int dup_mmap(struct mm_struct *mm
69 }
70 charge = 0;
71 if (mpnt->vm_flags & VM_ACCOUNT) {
72 - unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
73 + unsigned long len;
74 + len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
75 if (security_vm_enough_memory_mm(oldmm, len)) /* sic */
76 goto fail_nomem;
77 charge = len;