]>
Commit | Line | Data |
---|---|---|
4d1db308 TL |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: Vlastimil Babka <vbabka@suse.cz> | |
3 | Date: Fri, 16 Dec 2022 17:32:27 +0100 | |
4 | Subject: [PATCH] mm, mremap: fix mremap() expanding vma with addr inside vma | |
5 | MIME-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | commit 6f12be792fde994ed934168f93c2a0d2a0cf0bc5 upstream. | |
10 | ||
11 | Since 6.1 we have noticed random rpm install failures that were tracked to | |
12 | mremap() returning -ENOMEM and to commit ca3d76b0aa80 ("mm: add merging | |
13 | after mremap resize"). | |
14 | ||
15 | The problem occurs when mremap() expands a VMA in place, but using an | |
16 | starting address that's not vma->vm_start, but somewhere in the middle. | |
17 | The extension_pgoff calculation introduced by the commit is wrong in that | |
18 | case, so vma_merge() fails due to pgoffs not being compatible. Fix the | |
19 | calculation. | |
20 | ||
21 | By the way it seems that the situations, where rpm now expands a vma from | |
22 | the middle, were made possible also due to that commit, thanks to the | |
23 | improved vma merging. Yet it should work just fine, except for the buggy | |
24 | calculation. | |
25 | ||
26 | Link: https://lkml.kernel.org/r/20221216163227.24648-1-vbabka@suse.cz | |
27 | Reported-by: Jiri Slaby <jirislaby@kernel.org> | |
28 | Link: https://bugzilla.suse.com/show_bug.cgi?id=1206359 | |
29 | Fixes: ca3d76b0aa80 ("mm: add merging after mremap resize") | |
30 | Signed-off-by: Vlastimil Babka <vbabka@suse.cz> | |
31 | Cc: Jakub Matěna <matenajakub@gmail.com> | |
32 | Cc: "Kirill A . Shutemov" <kirill@shutemov.name> | |
33 | Cc: Liam Howlett <liam.howlett@oracle.com> | |
34 | Cc: Matthew Wilcox <willy@infradead.org> | |
35 | Cc: Mel Gorman <mgorman@techsingularity.net> | |
36 | Cc: Michal Hocko <mhocko@kernel.org> | |
37 | Cc: <stable@vger.kernel.org> | |
38 | Signed-off-by: Andrew Morton <akpm@linux-foundation.org> | |
39 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
40 | (cherry picked from commit 4d528dab403ba45db24769f5e5a9514ab0890351) | |
41 | Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com> | |
42 | --- | |
43 | mm/mremap.c | 3 ++- | |
44 | 1 file changed, 2 insertions(+), 1 deletion(-) | |
45 | ||
46 | diff --git a/mm/mremap.c b/mm/mremap.c | |
47 | index e465ffe279bb..fe587c5d6591 100644 | |
48 | --- a/mm/mremap.c | |
49 | +++ b/mm/mremap.c | |
50 | @@ -1016,7 +1016,8 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, | |
51 | long pages = (new_len - old_len) >> PAGE_SHIFT; | |
52 | unsigned long extension_start = addr + old_len; | |
53 | unsigned long extension_end = addr + new_len; | |
54 | - pgoff_t extension_pgoff = vma->vm_pgoff + (old_len >> PAGE_SHIFT); | |
55 | + pgoff_t extension_pgoff = vma->vm_pgoff + | |
56 | + ((extension_start - vma->vm_start) >> PAGE_SHIFT); | |
57 | ||
58 | if (vma->vm_flags & VM_ACCOUNT) { | |
59 | if (security_vm_enough_memory_mm(mm, pages)) { |