]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
queue mm-do-not-bug_on-on-incorrect-length-in-__mm_populat.patch for 4.9
authorSasha Levin <sashal@kernel.org>
Thu, 15 Nov 2018 17:35:57 +0000 (12:35 -0500)
committerSasha Levin <sashal@kernel.org>
Thu, 15 Nov 2018 17:35:57 +0000 (12:35 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.9/mm-do-not-bug_on-on-incorrect-length-in-__mm_populat.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/mm-do-not-bug_on-on-incorrect-length-in-__mm_populat.patch b/queue-4.9/mm-do-not-bug_on-on-incorrect-length-in-__mm_populat.patch
new file mode 100644 (file)
index 0000000..9ed6246
--- /dev/null
@@ -0,0 +1,131 @@
+From b9ef297c61321bc6c592bda54c510d0cb15974dc Mon Sep 17 00:00:00 2001
+From: Michal Hocko <mhocko@suse.com>
+Date: Tue, 13 Nov 2018 16:41:56 +0000
+Subject: mm: do not bug_on on incorrect length in __mm_populate()
+
+commit bb177a732c4369bb58a1fe1df8f552b6f0f7db5f upstream.
+
+syzbot has noticed that a specially crafted library can easily hit
+VM_BUG_ON in __mm_populate
+
+  kernel BUG at mm/gup.c:1242!
+  invalid opcode: 0000 [#1] SMP
+  CPU: 2 PID: 9667 Comm: a.out Not tainted 4.18.0-rc3 #644
+  Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 05/19/2017
+  RIP: 0010:__mm_populate+0x1e2/0x1f0
+  Code: 55 d0 65 48 33 14 25 28 00 00 00 89 d8 75 21 48 83 c4 20 5b 41 5c 41 5d 41 5e 41 5f 5d c3 e8 75 18 f1 ff 0f 0b e8 6e 18 f1 ff <0f> 0b 31 db eb c9 e8 93 06 e0 ff 0f 1f 00 55 48 89 e5 53 48 89 fb
+  Call Trace:
+     vm_brk_flags+0xc3/0x100
+     vm_brk+0x1f/0x30
+     load_elf_library+0x281/0x2e0
+     __ia32_sys_uselib+0x170/0x1e0
+     do_fast_syscall_32+0xca/0x420
+     entry_SYSENTER_compat+0x70/0x7f
+
+The reason is that the length of the new brk is not page aligned when we
+try to populate the it.  There is no reason to bug on that though.
+do_brk_flags already aligns the length properly so the mapping is
+expanded as it should.  All we need is to tell mm_populate about it.
+Besides that there is absolutely no reason to to bug_on in the first
+place.  The worst thing that could happen is that the last page wouldn't
+get populated and that is far from putting system into an inconsistent
+state.
+
+Fix the issue by moving the length sanitization code from do_brk_flags
+up to vm_brk_flags.  The only other caller of do_brk_flags is brk
+syscall entry and it makes sure to provide the proper length so t here
+is no need for sanitation and so we can use do_brk_flags without it.
+
+Also remove the bogus BUG_ONs.
+
+[osalvador@techadventures.net: fix up vm_brk_flags s@request@len@]
+Link: http://lkml.kernel.org/r/20180706090217.GI32658@dhcp22.suse.cz
+Signed-off-by: Michal Hocko <mhocko@suse.com>
+Reported-by: syzbot <syzbot+5dcb560fe12aa5091c06@syzkaller.appspotmail.com>
+Tested-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Reviewed-by: Oscar Salvador <osalvador@suse.de>
+Cc: Zi Yan <zi.yan@cs.rutgers.edu>
+Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: "Huang, Ying" <ying.huang@intel.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+[bwh: Backported to 4.9:
+ - There is no do_brk_flags() function; update do_brk()
+ - Adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/gup.c  |  2 --
+ mm/mmap.c | 19 ++++++++++---------
+ 2 files changed, 10 insertions(+), 11 deletions(-)
+
+diff --git a/mm/gup.c b/mm/gup.c
+index be4ccddac26f..d71da7216c6e 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -1122,8 +1122,6 @@ int __mm_populate(unsigned long start, unsigned long len, int ignore_errors)
+       int locked = 0;
+       long ret = 0;
+-      VM_BUG_ON(start & ~PAGE_MASK);
+-      VM_BUG_ON(len != PAGE_ALIGN(len));
+       end = start + len;
+       for (nstart = start; nstart < end; nstart = nend) {
+diff --git a/mm/mmap.c b/mm/mmap.c
+index aa97074a4a99..283755645d17 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -2876,21 +2876,15 @@ static inline void verify_mm_writelocked(struct mm_struct *mm)
+  *  anonymous maps.  eventually we may be able to do some
+  *  brk-specific accounting here.
+  */
+-static int do_brk(unsigned long addr, unsigned long request)
++static int do_brk(unsigned long addr, unsigned long len)
+ {
+       struct mm_struct *mm = current->mm;
+       struct vm_area_struct *vma, *prev;
+-      unsigned long flags, len;
++      unsigned long flags;
+       struct rb_node **rb_link, *rb_parent;
+       pgoff_t pgoff = addr >> PAGE_SHIFT;
+       int error;
+-      len = PAGE_ALIGN(request);
+-      if (len < request)
+-              return -ENOMEM;
+-      if (!len)
+-              return 0;
+-
+       flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
+       error = get_unmapped_area(NULL, addr, len, 0, MAP_FIXED);
+@@ -2959,12 +2953,19 @@ static int do_brk(unsigned long addr, unsigned long request)
+       return 0;
+ }
+-int vm_brk(unsigned long addr, unsigned long len)
++int vm_brk(unsigned long addr, unsigned long request)
+ {
+       struct mm_struct *mm = current->mm;
++      unsigned long len;
+       int ret;
+       bool populate;
++      len = PAGE_ALIGN(request);
++      if (len < request)
++              return -ENOMEM;
++      if (!len)
++              return 0;
++
+       if (down_write_killable(&mm->mmap_sem))
+               return -EINTR;
+-- 
+2.17.1
+
index ad295be262a0eabc1a30bfaffcb1c968749d79b4..fb7cc36bcc713d9e1bad7a8f04ddf0061a1e1e6d 100644 (file)
@@ -19,3 +19,4 @@ fuse-fix-use-after-free-in-fuse_dev_do_read.patch
 fuse-fix-use-after-free-in-fuse_dev_do_write.patch
 fuse-fix-blocked_waitq-wakeup.patch
 fuse-set-fr_sent-while-locked.patch
+mm-do-not-bug_on-on-incorrect-length-in-__mm_populat.patch