From: Oleg Nesterov 1. hugetlbfs_file_mmap() must check that vm_pgoff is hugepage aligned. 2. hugetlb_vmtruncate_list() confuses << with >> while converting vm_pgoff to huge page offset, and zaps wrong area. Signed-off-by: Oleg Nesterov Signed-off-by: Andrew Morton --- 25-akpm/fs/hugetlbfs/inode.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff -puN fs/hugetlbfs/inode.c~hugetlbfs-vm_pgoff-bugs fs/hugetlbfs/inode.c --- 25/fs/hugetlbfs/inode.c~hugetlbfs-vm_pgoff-bugs 2004-07-10 18:00:11.151776304 -0700 +++ 25-akpm/fs/hugetlbfs/inode.c 2004-07-10 18:00:11.155775696 -0700 @@ -52,6 +52,9 @@ static int hugetlbfs_file_mmap(struct fi loff_t len, vma_len; int ret; + if (vma->vm_pgoff & (HPAGE_SIZE / PAGE_SIZE - 1)) + return -EINVAL; + if (vma->vm_start & ~HPAGE_MASK) return -EINVAL; @@ -280,16 +283,16 @@ hugetlb_vmtruncate_list(struct prio_tree unsigned long v_length; unsigned long v_offset; - h_vm_pgoff = vma->vm_pgoff << (HPAGE_SHIFT - PAGE_SHIFT); - v_length = vma->vm_end - vma->vm_start; + h_vm_pgoff = vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT); v_offset = (h_pgoff - h_vm_pgoff) << HPAGE_SHIFT; - /* * Is this VMA fully outside the truncation point? */ if (h_vm_pgoff >= h_pgoff) v_offset = 0; + v_length = vma->vm_end - vma->vm_start; + zap_hugepage_range(vma, vma->vm_start + v_offset, v_length - v_offset); _