| From: Kees Cook <keescook@chromium.org> |
| Date: Tue, 2 Aug 2016 14:04:54 -0700 |
| Subject: mm: refuse wrapped vm_brk requests |
| |
| commit ba093a6d9397da8eafcfbaa7d95bd34255da39a0 upstream. |
| |
| The vm_brk() alignment calculations should refuse to overflow. The ELF |
| loader depending on this, but it has been fixed now. No other unsafe |
| callers have been found. |
| |
| Link: http://lkml.kernel.org/r/1468014494-25291-3-git-send-email-keescook@chromium.org |
| Signed-off-by: Kees Cook <keescook@chromium.org> |
| Reported-by: Hector Marco-Gisbert <hecmargi@upv.es> |
| Cc: Ismael Ripoll Ripoll <iripoll@upv.es> |
| Cc: Alexander Viro <viro@zeniv.linux.org.uk> |
| Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> |
| Cc: Oleg Nesterov <oleg@redhat.com> |
| Cc: Chen Gang <gang.chen.5i5j@gmail.com> |
| Cc: Michal Hocko <mhocko@suse.com> |
| Cc: Konstantin Khlebnikov <koct9i@gmail.com> |
| Cc: Andrea Arcangeli <aarcange@redhat.com> |
| Cc: Andrey Ryabinin <aryabinin@virtuozzo.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| [bwh: Backported to 3.16: adjust context] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| mm/mmap.c | 8 +++++--- |
| 1 file changed, 5 insertions(+), 3 deletions(-) |
| |
| --- a/mm/mmap.c |
| +++ b/mm/mmap.c |
| @@ -2751,16 +2751,18 @@ static inline void verify_mm_writelocked |
| * anonymous maps. eventually we may be able to do some |
| * brk-specific accounting here. |
| */ |
| -static unsigned long do_brk(unsigned long addr, unsigned long len) |
| +static unsigned long do_brk(unsigned long addr, unsigned long request) |
| { |
| struct mm_struct * mm = current->mm; |
| struct vm_area_struct * vma, * prev; |
| - unsigned long flags; |
| + unsigned long flags, len; |
| struct rb_node ** rb_link, * rb_parent; |
| pgoff_t pgoff = addr >> PAGE_SHIFT; |
| int error; |
| |
| - len = PAGE_ALIGN(len); |
| + len = PAGE_ALIGN(request); |
| + if (len < request) |
| + return -ENOMEM; |
| if (!len) |
| return addr; |
| |