fs/hugetlbfs/inode.c: fix bugs in hugetlb_vmtruncate_list() (CVE-2016-0617)
Fixes a regression in 4.3.
This commit is contained in:
parent
95ece6ebc6
commit
1c28b9c3ed
|
@ -1,6 +1,8 @@
|
|||
linux (4.4.1-1) UNRELEASED; urgency=medium
|
||||
|
||||
* iw_cxgb3: Fix incorrectly returning error on success (CVE-2015-8812)
|
||||
* fs/hugetlbfs/inode.c: fix bugs in hugetlb_vmtruncate_list() (CVE-2016-0617)
|
||||
(regression in 4.3)
|
||||
|
||||
-- Ben Hutchings <ben@decadent.org.uk> Fri, 12 Feb 2016 23:34:23 +0000
|
||||
|
||||
|
|
83
debian/patches/bugfix/all/fs-hugetlbfs-inode.c-fix-bugs-in-hugetlb_vmtruncate_.patch
vendored
Normal file
83
debian/patches/bugfix/all/fs-hugetlbfs-inode.c-fix-bugs-in-hugetlb_vmtruncate_.patch
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
From: Mike Kravetz <mike.kravetz@oracle.com>
|
||||
Date: Fri, 15 Jan 2016 16:57:37 -0800
|
||||
Subject: fs/hugetlbfs/inode.c: fix bugs in hugetlb_vmtruncate_list()
|
||||
Origin: https://git.kernel.org/linus/9aacdd354d197ad64685941b36d28ea20ab88757
|
||||
|
||||
Hillf Danton noticed bugs in the hugetlb_vmtruncate_list routine. The
|
||||
argument end is of type pgoff_t. It was being converted to a vaddr
|
||||
offset and passed to unmap_hugepage_range. However, end was also being
|
||||
used as an argument to the vma_interval_tree_foreach controlling loop.
|
||||
In addition, the conversion of end to vaddr offset was incorrect.
|
||||
|
||||
hugetlb_vmtruncate_list is called as part of a file truncate or
|
||||
fallocate hole punch operation.
|
||||
|
||||
When truncating a hugetlbfs file, this bug could prevent some pages from
|
||||
being unmapped. This is possible if there are multiple vmas mapping the
|
||||
file, and there is a sufficiently sized hole between the mappings. The
|
||||
size of the hole between two vmas (A,B) must be such that the starting
|
||||
virtual address of B is greater than (ending virtual address of A <<
|
||||
PAGE_SHIFT). In this case, the pages in B would not be unmapped. If
|
||||
pages are not properly unmapped during truncate, the following BUG is
|
||||
hit:
|
||||
|
||||
kernel BUG at fs/hugetlbfs/inode.c:428!
|
||||
|
||||
In the fallocate hole punch case, this bug could prevent pages from
|
||||
being unmapped as in the truncate case. However, for hole punch the
|
||||
result is that unmapped pages will not be removed during the operation.
|
||||
For hole punch, it is also possible that more pages than desired will be
|
||||
unmapped. This unnecessary unmapping will cause page faults to
|
||||
reestablish the mappings on subsequent page access.
|
||||
|
||||
Fixes: 1bfad99ab (" hugetlbfs: hugetlb_vmtruncate_list() needs to take a range")Reported-by: Hillf Danton <hillf.zj@alibaba-inc.com>
|
||||
Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
|
||||
Cc: Hugh Dickins <hughd@google.com>
|
||||
Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
|
||||
Cc: Davidlohr Bueso <dave@stgolabs.net>
|
||||
Cc: Dave Hansen <dave.hansen@linux.intel.com>
|
||||
Cc: <stable@vger.kernel.org> [4.3]
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
fs/hugetlbfs/inode.c | 19 +++++++++++--------
|
||||
1 file changed, 11 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
|
||||
index bbc333b01ca3..9c07d2d754c9 100644
|
||||
--- a/fs/hugetlbfs/inode.c
|
||||
+++ b/fs/hugetlbfs/inode.c
|
||||
@@ -463,6 +463,7 @@ hugetlb_vmdelete_list(struct rb_root *root, pgoff_t start, pgoff_t end)
|
||||
*/
|
||||
vma_interval_tree_foreach(vma, root, start, end ? end : ULONG_MAX) {
|
||||
unsigned long v_offset;
|
||||
+ unsigned long v_end;
|
||||
|
||||
/*
|
||||
* Can the expression below overflow on 32-bit arches?
|
||||
@@ -475,15 +476,17 @@ hugetlb_vmdelete_list(struct rb_root *root, pgoff_t start, pgoff_t end)
|
||||
else
|
||||
v_offset = 0;
|
||||
|
||||
- if (end) {
|
||||
- end = ((end - start) << PAGE_SHIFT) +
|
||||
- vma->vm_start + v_offset;
|
||||
- if (end > vma->vm_end)
|
||||
- end = vma->vm_end;
|
||||
- } else
|
||||
- end = vma->vm_end;
|
||||
+ if (!end)
|
||||
+ v_end = vma->vm_end;
|
||||
+ else {
|
||||
+ v_end = ((end - vma->vm_pgoff) << PAGE_SHIFT)
|
||||
+ + vma->vm_start;
|
||||
+ if (v_end > vma->vm_end)
|
||||
+ v_end = vma->vm_end;
|
||||
+ }
|
||||
|
||||
- unmap_hugepage_range(vma, vma->vm_start + v_offset, end, NULL);
|
||||
+ unmap_hugepage_range(vma, vma->vm_start + v_offset, v_end,
|
||||
+ NULL);
|
||||
}
|
||||
}
|
||||
|
|
@ -118,3 +118,4 @@ bugfix/all/usb-serial-visor-fix-crash-on-detecting-device-without-write_urbs.pat
|
|||
bugfix/all/tty-fix-unsafe-ldisc-reference-via-ioctl-tiocgetd.patch
|
||||
bugfix/all/pipe-limit-the-per-user-amount-of-pages-allocated-in.patch
|
||||
bugfix/all/iw_cxgb3-Fix-incorrectly-returning-error-on-success.patch
|
||||
bugfix/all/fs-hugetlbfs-inode.c-fix-bugs-in-hugetlb_vmtruncate_.patch
|
||||
|
|
Loading…
Reference in New Issue