From patchwork Fri Sep 7 22:42:58 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suresh Siddha X-Patchwork-Id: 182476 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from merlin.infradead.org (unknown [IPv6:2001:4978:20e::2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E8E602C007E for ; Sat, 8 Sep 2012 08:45:14 +1000 (EST) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TA7HS-0005nS-Ap; Fri, 07 Sep 2012 22:44:06 +0000 Received: from mga11.intel.com ([192.55.52.93]) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TA7HO-0005nE-Ml for linux-mtd@lists.infradead.org; Fri, 07 Sep 2012 22:44:03 +0000 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 07 Sep 2012 15:43:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.80,388,1344236400"; d="scan'208";a="219334848" Received: from sbsiddha-desk.sc.intel.com (HELO [10.3.79.149]) ([10.3.79.149]) by fmsmga002.fm.intel.com with ESMTP; 07 Sep 2012 15:43:59 -0700 Subject: Re: mtd: kernel BUG at arch/x86/mm/pat.c:279! From: Suresh Siddha To: Linus Torvalds Date: Fri, 07 Sep 2012 15:42:58 -0700 In-Reply-To: References: <1340959739.2936.28.camel@lappy> Organization: Intel Corp X-Mailer: Evolution 3.0.3 (3.0.3-1.fc15) Message-ID: <1347057778.26695.68.camel@sbsiddha-desk.sc.intel.com> Mime-Version: 1.0 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -6.9 (------) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-6.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/, high trust [192.55.52.93 listed in list.dnswl.org] 0.0 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: "linux-kernel@vger.kernel.org" , linux-mm , linux-mtd@lists.infradead.org, Sasha Levin , Dave Jones , Andrew Morton , dwmw2@infradead.org X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: Suresh Siddha List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org On Fri, 2012-09-07 at 11:14 -0700, Linus Torvalds wrote: > Guys, this looks like a MTD and/or io_remap_pfn_range() bug, and it's > not getting any traction. > > What the f*ck is mtd_mmap() doing, and why? The problem seems to be an > overflow condition, because reserve_pfn_range() does > > reserve_memtype(paddr, paddr + size, want_flags, &flags); > > and then the BUG_ON() in reserve_memtype is > > BUG_ON(start >= end); > > so it very much looks like a paddr+size overflow. However, that makes > little sense too, since we're working in "u64", so I suspect the > overflow has happened somewhere earlier. > > I really don't see where, though. Could somebody please take a look? > The mtdchar_mmap() types seem insane (why "u32" for len, for example? > And that whole > > off = vma->vm_pgoff << PAGE_SHIFT; > > thing looks like it would overflow, since the whole point of pgoff is > that if you shift it up by PAGE_SHIFT you need to also extend to > 64-bit etc. > > So I would *guess* that it's the mtdchar_mmap() stuff that overflows > due to bad types, but maybe it does deeper than that? > I started to look into this to see if this is a PAT issue but it does indeed appear to be a mtd mmap issue. Sasha, Does the appended fix the issue for you? --8<-- From: Suresh Siddha Subject: mtd: check the starting offset to be mmap'd We need to check if both the starting offset aswell the total length being mmap'd are with in the limits. With a large starting offset, offset + (length-to-be-mapped) can wrap and appear smaller than the limit. Need to check both start and end. Also fix the types of the variables start, off, len. Signed-off-by: Suresh Siddha --- drivers/mtd/mtdchar.c | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index f2f482b..f79c0fa 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -1132,16 +1132,15 @@ static int mtdchar_mmap(struct file *file, struct vm_area_struct *vma) struct mtd_file_info *mfi = file->private_data; struct mtd_info *mtd = mfi->mtd; struct map_info *map = mtd->priv; - unsigned long start; - unsigned long off; - u32 len; + resource_size_t start, off; + unsigned long len; if (mtd->type == MTD_RAM || mtd->type == MTD_ROM) { off = vma->vm_pgoff << PAGE_SHIFT; start = map->phys; len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size); start &= PAGE_MASK; - if ((vma->vm_end - vma->vm_start + off) > len) + if (off >= len || (vma->vm_end - vma->vm_start + off) > len) return -EINVAL; off += start;