mremap() triggers a WARN_ON_ONCE() in untrack_pfn() in the 3.18 kernel |
||||
Issue descriptionTo reproduce, compile and run the attached program (generated by syzkaller): ------------[ cut here ]------------ WARNING: CPU: 0 PID: 3374 at /mnt/host/source/src/third_party/kernel/v3.18/arch/x86/mm/pat.c:899 untrack_pfn+0xab/0x13e() Modules linked in: i2c_dev uinput sr_mod cdrom bluetooth zram fuse cfg80211 nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_filter ip6_tables virtio_net i2c_piix4 snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device ppp_async ppp_generic slhc tun CPU: 0 PID: 3374 Comm: warn_once_untra Not tainted 3.18.0 #19 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 0000000000000009 00000000c79d2202 ffff88001940fae8 ffffffff81b50047 0000000000000300 ffffffffc79d2202 0000000000000000 ffff8800195ea100 ffff88001940fb38 ffffffff810636af ffff88001940fb58 ffffffff810589d5 Call Trace: [< inline >] __dump_stack /mnt/host/source/src/third_party/kernel/v3.18/lib/dump_stack.c:15 [<ffffffff81b50047>] dump_stack+0x74/0xb3 /mnt/host/source/src/third_party/kernel/v3.18/lib/dump_stack.c:50 [<ffffffff810636af>] warn_slowpath_common+0xa9/0xc7 /mnt/host/source/src/third_party/kernel/v3.18/kernel/panic.c:441 [<ffffffff810589d5>] ? untrack_pfn+0xab/0x13e /mnt/host/source/src/third_party/kernel/v3.18/arch/x86/mm/pat.c:899 [< inline >] ? mremap_to /mnt/host/source/src/third_party/kernel/v3.18/mm/mremap.c:453 [< inline >] ? SYSC_mremap /mnt/host/source/src/third_party/kernel/v3.18/mm/mremap.c:516 [<ffffffff811b1535>] ? SyS_mremap+0x38d/0x71c /mnt/host/source/src/third_party/kernel/v3.18/mm/mremap.c:483 [<ffffffff8106380b>] warn_slowpath_null+0x31/0x33 /mnt/host/source/src/third_party/kernel/v3.18/kernel/panic.c:474 [<ffffffff810589d5>] untrack_pfn+0xab/0x13e /mnt/host/source/src/third_party/kernel/v3.18/arch/x86/mm/pat.c:899 [< inline >] ? set_track /mnt/host/source/src/third_party/kernel/v3.18/mm/kasan/kasan.c:462 [<ffffffff811c7609>] ? kasan_slab_free+0x62/0x7e /mnt/host/source/src/third_party/kernel/v3.18/mm/kasan/kasan.c:501 [<ffffffff811c56d5>] ? kmem_cache_free+0x3a/0x81 /mnt/host/source/src/third_party/kernel/v3.18/mm/slab.c:3537 [<ffffffff811a2ce8>] unmap_single_vma+0xdc/0x92e /mnt/host/source/src/third_party/kernel/v3.18/mm/memory.c:1327 [< inline >] ? __rb_change_child /mnt/host/source/src/third_party/kernel/v3.18/include/linux/rbtree_augmented.h:125 [<ffffffff813adafb>] ? __rb_rotate_set_parents+0x5f/0x9d /mnt/host/source/src/third_party/kernel/v3.18/lib/rbtree.c:69 [<ffffffff811aad12>] ? vma_gap_callbacks_rotate+0xde/0xee /mnt/host/source/src/third_party/kernel/v3.18/mm/mmap.c:491 [<ffffffff811aac34>] ? can_vma_merge_before+0x176/0x176 /mnt/host/source/src/third_party/kernel/v3.18/mm/mmap.c:1002 [< inline >] ? __rb_insert /mnt/host/source/src/third_party/kernel/v3.18/lib/rbtree.c:191 [<ffffffff813ae3c6>] ? __rb_insert_augmented+0x284/0x293 /mnt/host/source/src/third_party/kernel/v3.18/lib/rbtree.c:411 [<ffffffff811a40f9>] unmap_vmas+0x94/0xa3 /mnt/host/source/src/third_party/kernel/v3.18/mm/memory.c:1378 [<ffffffff811aa09d>] unmap_region+0x124/0x1b2 /mnt/host/source/src/third_party/kernel/v3.18/mm/mmap.c:2425 [<ffffffff811aa963>] ? vma_rb_erase+0x389/0x398 /mnt/host/source/src/third_party/kernel/v3.18/mm/mmap.c:531 [<ffffffff811ad007>] do_munmap+0x49f/0x582 /mnt/host/source/src/third_party/kernel/v3.18/mm/mmap.c:2623 [<ffffffff811b10a4>] move_vma+0x2d1/0x3d5 /mnt/host/source/src/third_party/kernel/v3.18/mm/mremap.c:321 [< inline >] mremap_to /mnt/host/source/src/third_party/kernel/v3.18/mm/mremap.c:453 [< inline >] SYSC_mremap /mnt/host/source/src/third_party/kernel/v3.18/mm/mremap.c:516 [<ffffffff811b1535>] SyS_mremap+0x38d/0x71c /mnt/host/source/src/third_party/kernel/v3.18/mm/mremap.c:483 [<ffffffff81b57cdc>] system_call_fastpath+0x1c/0x21 /mnt/host/source/src/third_party/kernel/v3.18/arch/x86/kernel/entry_64.S:436 ---[ end trace 2cf6cad0524efa17 ]--- Most likely we need to backport https://github.com/torvalds/linux/commit/d9fe4fab11976e56b2e992980bf6ce948bdf02ac to 3.18
,
Jul 8 2016
The following revision refers to this bug: https://chromium.googlesource.com/chromiumos/third_party/kernel/+/ff10d9597b39860075051fbf46ff167cd58224f1 commit ff10d9597b39860075051fbf46ff167cd58224f1 Author: Toshi Kani <toshi.kani@hpe.com> Date: Wed Dec 23 00:54:23 2015 UPSTREAM: x86/mm/pat: Add untrack_pfn_moved for mremap mremap() with MREMAP_FIXED on a VM_PFNMAP range causes the following WARN_ON_ONCE() message in untrack_pfn(). WARNING: CPU: 1 PID: 3493 at arch/x86/mm/pat.c:985 untrack_pfn+0xbd/0xd0() Call Trace: [<ffffffff817729ea>] dump_stack+0x45/0x57 [<ffffffff8109e4b6>] warn_slowpath_common+0x86/0xc0 [<ffffffff8109e5ea>] warn_slowpath_null+0x1a/0x20 [<ffffffff8106a88d>] untrack_pfn+0xbd/0xd0 [<ffffffff811d2d5e>] unmap_single_vma+0x80e/0x860 [<ffffffff811d3725>] unmap_vmas+0x55/0xb0 [<ffffffff811d916c>] unmap_region+0xac/0x120 [<ffffffff811db86a>] do_munmap+0x28a/0x460 [<ffffffff811dec33>] move_vma+0x1b3/0x2e0 [<ffffffff811df113>] SyS_mremap+0x3b3/0x510 [<ffffffff817793ee>] entry_SYSCALL_64_fastpath+0x12/0x71 MREMAP_FIXED moves a pfnmap from old vma to new vma. untrack_pfn() is called with the old vma after its pfnmap page table has been removed, which causes follow_phys() to fail. The new vma has a new pfnmap to the same pfn & cache type with VM_PAT set. Therefore, we only need to clear VM_PAT from the old vma in this case. Add untrack_pfn_moved(), which clears VM_PAT from a given old vma. move_vma() is changed to call this function with the old vma when VM_PFNMAP is set. move_vma() then calls do_munmap(), and untrack_pfn() is a no-op since VM_PAT is cleared. Reported-by: Stas Sergeev <stsp@list.ru> Signed-off-by: Toshi Kani <toshi.kani@hpe.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Borislav Petkov <bp@suse.de> Cc: linux-mm@kvack.org Link: http://lkml.kernel.org/r/1450832064-10093-2-git-send-email-toshi.kani@hpe.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de> BUG=chromium:626001 TEST=KASAN doesn't report errors for the given repro (cherry picked from commit d9fe4fab11976e56b2e992980bf6ce948bdf02ac) Signed-off-by: Alexander Potapenko <glider@google.com> Change-Id: I57a5e0de1bb6e9ae2295f589271fb0b5ea225177 Reviewed-on: https://chromium-review.googlesource.com/359220 Commit-Ready: Alexander Potapenko <glider@chromium.org> Tested-by: Alexander Potapenko <glider@chromium.org> Reviewed-by: Nicolas Boichat <drinkcat@chromium.org> [modify] https://crrev.com/ff10d9597b39860075051fbf46ff167cd58224f1/mm/mremap.c [modify] https://crrev.com/ff10d9597b39860075051fbf46ff167cd58224f1/arch/x86/mm/pat.c [modify] https://crrev.com/ff10d9597b39860075051fbf46ff167cd58224f1/include/asm-generic/pgtable.h
,
Jul 26 2016
The bug is also reproducible with syzkaller on the kernel 4.4.
,
Jul 29 2016
The following revision refers to this bug: https://chromium.googlesource.com/chromiumos/third_party/kernel/+/a46a0b8f266e7490557a2a1a28ebdaf849d1fb51 commit a46a0b8f266e7490557a2a1a28ebdaf849d1fb51 Author: Toshi Kani <toshi.kani@hpe.com> Date: Wed Dec 23 00:54:23 2015 UPSTREAM: x86/mm/pat: Add untrack_pfn_moved for mremap mremap() with MREMAP_FIXED on a VM_PFNMAP range causes the following WARN_ON_ONCE() message in untrack_pfn(). WARNING: CPU: 1 PID: 3493 at arch/x86/mm/pat.c:985 untrack_pfn+0xbd/0xd0() Call Trace: [<ffffffff817729ea>] dump_stack+0x45/0x57 [<ffffffff8109e4b6>] warn_slowpath_common+0x86/0xc0 [<ffffffff8109e5ea>] warn_slowpath_null+0x1a/0x20 [<ffffffff8106a88d>] untrack_pfn+0xbd/0xd0 [<ffffffff811d2d5e>] unmap_single_vma+0x80e/0x860 [<ffffffff811d3725>] unmap_vmas+0x55/0xb0 [<ffffffff811d916c>] unmap_region+0xac/0x120 [<ffffffff811db86a>] do_munmap+0x28a/0x460 [<ffffffff811dec33>] move_vma+0x1b3/0x2e0 [<ffffffff811df113>] SyS_mremap+0x3b3/0x510 [<ffffffff817793ee>] entry_SYSCALL_64_fastpath+0x12/0x71 MREMAP_FIXED moves a pfnmap from old vma to new vma. untrack_pfn() is called with the old vma after its pfnmap page table has been removed, which causes follow_phys() to fail. The new vma has a new pfnmap to the same pfn & cache type with VM_PAT set. Therefore, we only need to clear VM_PAT from the old vma in this case. Add untrack_pfn_moved(), which clears VM_PAT from a given old vma. move_vma() is changed to call this function with the old vma when VM_PFNMAP is set. move_vma() then calls do_munmap(), and untrack_pfn() is a no-op since VM_PAT is cleared. Reported-by: Stas Sergeev <stsp@list.ru> Signed-off-by: Toshi Kani <toshi.kani@hpe.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Borislav Petkov <bp@suse.de> Cc: linux-mm@kvack.org Link: http://lkml.kernel.org/r/1450832064-10093-2-git-send-email-toshi.kani@hpe.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de> BUG=chromium:626001 TEST=KASAN doesn't report errors for the given repro (cherry picked from commit d9fe4fab11976e56b2e992980bf6ce948bdf02ac) Signed-off-by: Alexander Potapenko <glider@google.com> Change-Id: I0c8e08ae8111891a960f5991317b469f3da66372 Reviewed-on: https://chromium-review.googlesource.com/363331 Commit-Ready: Alexander Potapenko <glider@chromium.org> Tested-by: Alexander Potapenko <glider@chromium.org> Reviewed-by: Guenter Roeck <groeck@chromium.org> [modify] https://crrev.com/a46a0b8f266e7490557a2a1a28ebdaf849d1fb51/mm/mremap.c [modify] https://crrev.com/a46a0b8f266e7490557a2a1a28ebdaf849d1fb51/arch/x86/mm/pat.c [modify] https://crrev.com/a46a0b8f266e7490557a2a1a28ebdaf849d1fb51/include/asm-generic/pgtable.h
,
Jan 8 2018
|
||||
►
Sign in to add a comment |
||||
Comment 1 by glider@chromium.org
, Jul 6 2016952 bytes
952 bytes View Download