diff options
| author | Dave Airlie <airlied@redhat.com> | 2018-03-28 14:30:41 +1000 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2018-03-28 14:30:41 +1000 |
| commit | 2b4f44eec2be2688511c2b617d0e1b4f94c45ba4 (patch) | |
| tree | 533c03602f4ae6d6404db6fa56c88e6f83e1bebe /fs/hugetlbfs/inode.c | |
| parent | 33d009cd889490838c5db9b9339856c9e3d3facc (diff) | |
| parent | 3eb2ce825ea1ad89d20f7a3b5780df850e4be274 (diff) | |
| download | talos-op-linux-2b4f44eec2be2688511c2b617d0e1b4f94c45ba4.tar.gz talos-op-linux-2b4f44eec2be2688511c2b617d0e1b4f94c45ba4.zip | |
Backmerge tag 'v4.16-rc7' into drm-next
Linux 4.16-rc7
This was requested by Daniel, and things were getting
a bit hard to reconcile, most of the conflicts were
trivial though.
Diffstat (limited to 'fs/hugetlbfs/inode.c')
| -rw-r--r-- | fs/hugetlbfs/inode.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 8fe1b0aa2896..b9a254dcc0e7 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -108,6 +108,16 @@ static void huge_pagevec_release(struct pagevec *pvec) pagevec_reinit(pvec); } +/* + * Mask used when checking the page offset value passed in via system + * calls. This value will be converted to a loff_t which is signed. + * Therefore, we want to check the upper PAGE_SHIFT + 1 bits of the + * value. The extra bit (- 1 in the shift value) is to take the sign + * bit into account. + */ +#define PGOFF_LOFFT_MAX \ + (((1UL << (PAGE_SHIFT + 1)) - 1) << (BITS_PER_LONG - (PAGE_SHIFT + 1))) + static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) { struct inode *inode = file_inode(file); @@ -127,12 +137,13 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_ops = &hugetlb_vm_ops; /* - * Offset passed to mmap (before page shift) could have been - * negative when represented as a (l)off_t. + * page based offset in vm_pgoff could be sufficiently large to + * overflow a (l)off_t when converted to byte offset. */ - if (((loff_t)vma->vm_pgoff << PAGE_SHIFT) < 0) + if (vma->vm_pgoff & PGOFF_LOFFT_MAX) return -EINVAL; + /* must be huge page aligned */ if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT)) return -EINVAL; |

