diff mbox series

mmap: Fix copy_vma() failure path

Message ID 20221011203621.1446507-1-Liam.Howlett@oracle.com (mailing list archive)
State New
Headers show
Series mmap: Fix copy_vma() failure path | expand

Commit Message

Liam R. Howlett Oct. 11, 2022, 8:36 p.m. UTC
The anon vma was not unlinked and the file was not closed in the failure
path when the machine runs out of memory during the maple tree
modification.  This caused a memory leak of the anon vma chain and vma
since neither would be freed.

Reported-by: Lukas Bulwahn <lukas.bulwahn@gmail.com>
Fixes: 524e00b36e8c (mm: remove rb tree.)
Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
---
 mm/mmap.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Lukas Bulwahn Oct. 12, 2022, 9:41 a.m. UTC | #1
On Tue, Oct 11, 2022 at 10:36 PM Liam Howlett <liam.howlett@oracle.com> wrote:
>
> The anon vma was not unlinked and the file was not closed in the failure
> path when the machine runs out of memory during the maple tree
> modification.  This caused a memory leak of the anon vma chain and vma
> since neither would be freed.
>
> Reported-by: Lukas Bulwahn <lukas.bulwahn@gmail.com>
> Fixes: 524e00b36e8c (mm: remove rb tree.)
> Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
> ---

Here my detailed test report:

First, I ran the reproducer
https://elisa-builder-00.iol.unh.edu/syzkaller-next/report?id=3113810b9abd3dfeb581759df93d3171d1a90f18
on the latest commit from Linus' tree, i.e., commit 49da07006239.
This resulted in the following kernel crash report on x86_64 defconfig
+ syzkaller-recommended debug features:

[  632.446911] kmemleak: 2 new suspected memory leaks (see
/sys/kernel/debug/kmemleak)
[  642.194797] kmemleak: 2 new suspected memory leaks (see
/sys/kernel/debug/kmemleak)

BUG: memory leak
unreferenced object 0xffff88800eab3220 (size 208):
  comm "a.out", pid 411, jiffies 4295289355 (age 20.054s)
  hex dump (first 32 bytes):
    20 32 ab 0e 80 88 ff ff 00 00 00 00 00 00 00 00   2..............
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  backtrace:
    [<000000006344da94>] __anon_vma_prepare+0x288/0x520
    [<0000000079cb6e3d>] __handle_mm_fault+0x1672/0x1a90
    [<000000003165d13e>] handle_mm_fault+0x177/0x520
    [<00000000d502ed60>] __get_user_pages+0x696/0x13b0
    [<000000000c44f161>] populate_vma_page_range+0x242/0x320
    [<00000000429a417a>] __mm_populate+0x1c6/0x3b0
    [<00000000988f9924>] do_mlock+0x3ad/0x6f0
    [<0000000099ba0e21>] __x64_sys_mlock2+0xba/0x100
    [<00000000a302ea0e>] do_syscall_64+0x3a/0x90
    [<0000000069487f88>] entry_SYSCALL_64_after_hwframe+0x63/0xcd

BUG: memory leak
unreferenced object 0xffff88800ef27ba0 (size 64):
  comm "a.out", pid 411, jiffies 4295289357 (age 20.053s)
  hex dump (first 32 bytes):
    30 3c 94 09 80 88 ff ff 20 32 ab 0e 80 88 ff ff  0<...... 2......
    78 3c 94 09 80 88 ff ff 78 3c 94 09 80 88 ff ff  x<......x<......
  backtrace:
    [<00000000ecf2fb6f>] anon_vma_clone+0xd3/0x590
    [<00000000e1cdd897>] copy_vma+0x3ea/0x7f0
    [<00000000ef59b15d>] move_vma.isra.48+0x8e6/0xf40
    [<00000000cf84e8ba>] mremap_to.isra.49+0x4d0/0x6c0
    [<00000000cf08a1f8>] __x64_sys_mremap+0x9cc/0xf20
    [<00000000a302ea0e>] do_syscall_64+0x3a/0x90
    [<0000000069487f88>] entry_SYSCALL_64_after_hwframe+0x63/0xcd

BUG: memory leak
unreferenced object 0xffff88800df86330 (size 208):
  comm "a.out", pid 412, jiffies 4295296993 (age 12.417s)
  hex dump (first 32 bytes):
    30 63 f8 0d 80 88 ff ff 00 00 00 00 00 00 00 00  0c..............
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  backtrace:
    [<000000006344da94>] __anon_vma_prepare+0x288/0x520
    [<0000000079cb6e3d>] __handle_mm_fault+0x1672/0x1a90
    [<000000003165d13e>] handle_mm_fault+0x177/0x520
    [<00000000d502ed60>] __get_user_pages+0x696/0x13b0
    [<000000000c44f161>] populate_vma_page_range+0x242/0x320
    [<00000000429a417a>] __mm_populate+0x1c6/0x3b0
    [<00000000988f9924>] do_mlock+0x3ad/0x6f0
    [<0000000099ba0e21>] __x64_sys_mlock2+0xba/0x100
    [<00000000a302ea0e>] do_syscall_64+0x3a/0x90
    [<0000000069487f88>] entry_SYSCALL_64_after_hwframe+0x63/0xcd

BUG: memory leak
unreferenced object 0xffff888015235180 (size 64):
  comm "a.out", pid 412, jiffies 4295296995 (age 12.415s)
  hex dump (first 32 bytes):
    00 fd 57 0d 80 88 ff ff 30 63 f8 0d 80 88 ff ff  ..W.....0c......
    48 fd 57 0d 80 88 ff ff 48 fd 57 0d 80 88 ff ff  H.W.....H.W.....
  backtrace:
    [<00000000ecf2fb6f>] anon_vma_clone+0xd3/0x590
    [<00000000e1cdd897>] copy_vma+0x3ea/0x7f0
    [<00000000ef59b15d>] move_vma.isra.48+0x8e6/0xf40
    [<00000000cf84e8ba>] mremap_to.isra.49+0x4d0/0x6c0
    [<00000000cf08a1f8>] __x64_sys_mremap+0x9cc/0xf20
    [<00000000a302ea0e>] do_syscall_64+0x3a/0x90
    [<0000000069487f88>] entry_SYSCALL_64_after_hwframe+0x63/0xcd


This is just as expected and as I reported it to Liam.

Then, I applied this patch here, rebuilt the kernel and re-ran the
reproducer. After roughly running the reproducer for 15 minutes, it
did not show any kernel crash report. So, the patch seems to have
solved the reported issue.

Tested-by: Lukas Bulwahn <lukas.bulwahn@gmail.com>

Thanks, Liam.

Lukas
diff mbox series

Patch

diff --git a/mm/mmap.c b/mm/mmap.c
index 74c0e3784500..5855f26639f9 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -3234,6 +3234,11 @@  struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
 out_vma_link:
 	if (new_vma->vm_ops && new_vma->vm_ops->close)
 		new_vma->vm_ops->close(new_vma);
+
+	if (new_vma->vm_file)
+		fput(new_vma->vm_file);
+
+	unlink_anon_vmas(new_vma);
 out_free_mempol:
 	mpol_put(vma_policy(new_vma));
 out_free_vma: