From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751746AbdDNESC convert rfc822-to-8bit (ORCPT ); Fri, 14 Apr 2017 00:18:02 -0400 Received: from tyo161.gate.nec.co.jp ([114.179.232.161]:42376 "EHLO tyo161.gate.nec.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751522AbdDNER7 (ORCPT ); Fri, 14 Apr 2017 00:17:59 -0400 From: Naoya Horiguchi To: Mike Kravetz CC: "linux-mm@kvack.org" , "linux-kernel@vger.kernel.org" , Vegard Nossum , Dmitry Vyukov , Hillf Danton , Michal Hocko , "Kirill A . Shutemov" , Andrey Ryabinin , Andrew Morton Subject: Re: [PATCH] hugetlbfs: fix offset overflow in huegtlbfs mmap Thread-Topic: [PATCH] hugetlbfs: fix offset overflow in huegtlbfs mmap Thread-Index: AQHSsxZkjTMJHDy4hEGBUT6eou/C9qHDolkA Date: Fri, 14 Apr 2017 03:32:15 +0000 Message-ID: <20170414033210.GA12973@hori1.linux.bs1.fc.nec.co.jp> References: <1491951118-30678-1-git-send-email-mike.kravetz@oracle.com> In-Reply-To: <1491951118-30678-1-git-send-email-mike.kravetz@oracle.com> Accept-Language: en-US, ja-JP Content-Language: ja-JP X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.128.101.18] Content-Type: text/plain; charset="iso-2022-jp" Content-ID: Content-Transfer-Encoding: 8BIT MIME-Version: 1.0 X-TM-AS-MML: disable Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Apr 11, 2017 at 03:51:58PM -0700, Mike Kravetz wrote: ... > diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c > index 7163fe0..dde8613 100644 > --- a/fs/hugetlbfs/inode.c > +++ b/fs/hugetlbfs/inode.c > @@ -136,17 +136,26 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) > vma->vm_flags |= VM_HUGETLB | VM_DONTEXPAND; > vma->vm_ops = &hugetlb_vm_ops; > > + /* > + * Offset passed to mmap (before page shift) could have been > + * negative when represented as a (l)off_t. > + */ > + if (((loff_t)vma->vm_pgoff << PAGE_SHIFT) < 0) > + return -EINVAL; > + > if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT)) > return -EINVAL; > > vma_len = (loff_t)(vma->vm_end - vma->vm_start); > + len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); > + /* check for overflow */ > + if (len < vma_len) > + return -EINVAL; Andrew sent this patch to Linus today, so I know it's a little too late, but I think that getting len directly from vma like below might be a simpler fix. len = (loff_t)(vma->vm_end - vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT)); This shouldn't overflow because vma->vm_{end|start|pgoff} are unsigned long, but if worried you can add VM_BUG_ON_VMA(len < 0, vma). Thanks, Naoya Horiguchi > > inode_lock(inode); > file_accessed(file); > > ret = -ENOMEM; > - len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); > - > if (hugetlb_reserve_pages(inode, > vma->vm_pgoff >> huge_page_order(h), > len >> huge_page_shift(h), vma, > @@ -155,7 +164,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) > > ret = 0; > if (vma->vm_flags & VM_WRITE && inode->i_size < len) > - inode->i_size = len; > + i_size_write(inode, len); > out: > inode_unlock(inode); > > -- > 2.7.4 > >