From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Suresh Siddha <suresh.b.siddha@intel.com>,
Artem Bityutskiy <dedekind1@gmail.com>,
David Woodhouse <dwmw2@infradead.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Ben Hutchings <ben@decadent.org.uk>,
Brad Spengler <spender@grsecurity.net>,
linux-mtd@lists.infradead.org
Subject: [ 10/11] mtdchar: fix offset overflow detection
Date: Sun, 14 Apr 2013 19:17:42 -0700 [thread overview]
Message-ID: <20130415020614.846683113@linuxfoundation.org> (raw)
In-Reply-To: <20130415020614.067692418@linuxfoundation.org>
3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Torvalds <torvalds@linux-foundation.org>
commit 9c603e53d380459fb62fec7cd085acb0b74ac18f upstream.
Sasha Levin has been running trinity in a KVM tools guest, and was able
to trigger the BUG_ON() at arch/x86/mm/pat.c:279 (verifying the range of
the memory type). The call trace showed that it was mtdchar_mmap() that
created an invalid remap_pfn_range().
The problem is that mtdchar_mmap() does various really odd and subtle
things with the vma page offset etc, and uses the wrong types (and the
wrong overflow) detection for it.
For example, the page offset may well be 32-bit on a 32-bit
architecture, but after shifting it up by PAGE_SHIFT, we need to use a
potentially 64-bit resource_size_t to correctly hold the full value.
Also, we need to check that the vma length plus offset doesn't overflow
before we check that it is smaller than the length of the mtdmap region.
This fixes things up and tries to make the code a bit easier to read.
Reported-and-tested-by: Sasha Levin <levinsasha928@gmail.com>
Acked-by: Suresh Siddha <suresh.b.siddha@intel.com>
Acked-by: Artem Bityutskiy <dedekind1@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: linux-mtd@lists.infradead.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Ben Hutchings <ben@decadent.org.uk>
Cc: Brad Spengler <spender@grsecurity.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mtd/mtdchar.c | 48 ++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 42 insertions(+), 6 deletions(-)
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1064,6 +1064,33 @@ static unsigned long mtd_get_unmapped_ar
}
#endif
+static inline unsigned long get_vm_size(struct vm_area_struct *vma)
+{
+ return vma->vm_end - vma->vm_start;
+}
+
+static inline resource_size_t get_vm_offset(struct vm_area_struct *vma)
+{
+ return (resource_size_t) vma->vm_pgoff << PAGE_SHIFT;
+}
+
+/*
+ * Set a new vm offset.
+ *
+ * Verify that the incoming offset really works as a page offset,
+ * and that the offset and size fit in a resource_size_t.
+ */
+static inline int set_vm_offset(struct vm_area_struct *vma, resource_size_t off)
+{
+ pgoff_t pgoff = off >> PAGE_SHIFT;
+ if (off != (resource_size_t) pgoff << PAGE_SHIFT)
+ return -EINVAL;
+ if (off + get_vm_size(vma) - 1 < off)
+ return -EINVAL;
+ vma->vm_pgoff = pgoff;
+ return 0;
+}
+
/*
* set up a mapping for shared memory segments
*/
@@ -1073,20 +1100,29 @@ static int mtd_mmap(struct file *file, s
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, vma_len;
if (mtd->type == MTD_RAM || mtd->type == MTD_ROM) {
- off = vma->vm_pgoff << PAGE_SHIFT;
+ off = get_vm_offset(vma);
start = map->phys;
len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size);
start &= PAGE_MASK;
- if ((vma->vm_end - vma->vm_start + off) > len)
+ vma_len = get_vm_size(vma);
+
+ /* Overflow in off+len? */
+ if (vma_len + off < off)
+ return -EINVAL;
+ /* Does it fit in the mapping? */
+ if (vma_len + off > len)
return -EINVAL;
off += start;
- vma->vm_pgoff = off >> PAGE_SHIFT;
+ /* Did that overflow? */
+ if (off < start)
+ return -EINVAL;
+ if (set_vm_offset(vma, off) < 0)
+ return -EINVAL;
vma->vm_flags |= VM_IO | VM_RESERVED;
#ifdef pgprot_noncached
next prev parent reply other threads:[~2013-04-15 2:17 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-15 2:17 [ 00/11] 3.0.74-stable review Greg Kroah-Hartman
2013-04-15 2:17 ` [ 01/11] ALSA: usb-audio: fix endianness bug in snd_nativeinstruments_* Greg Kroah-Hartman
2013-04-15 2:17 ` [ 02/11] x86-32, mm: Rip out x86_32 NUMA remapping code Greg Kroah-Hartman
2013-04-15 2:17 ` [ 03/11] ASoC: wm8903: Fix the bypass to HP/LINEOUT when no DAC or ADC is running Greg Kroah-Hartman
2013-04-15 2:17 ` [ 04/11] tracing: Fix double free when function profile init failed Greg Kroah-Hartman
2013-04-15 2:17 ` [ 05/11] PM / reboot: call syscore_shutdown() after disable_nonboot_cpus() Greg Kroah-Hartman
2013-04-15 2:17 ` [ 06/11] target: Fix incorrect fallthrough of ALUA Standby/Offline/Transition CDBs Greg Kroah-Hartman
2013-04-15 2:17 ` [ 07/11] sched_clock: Prevent 64bit inatomicity on 32bit systems Greg Kroah-Hartman
2013-04-15 2:17 ` [ 08/11] x86, mm, paravirt: Fix vmalloc_fault oops during lazy MMU updates Greg Kroah-Hartman
2013-04-15 2:17 ` [ 09/11] x86, mm: Patch out arch_flush_lazy_mmu_mode() when running on bare metal Greg Kroah-Hartman
2013-04-15 2:17 ` Greg Kroah-Hartman [this message]
2013-04-15 20:55 ` [ 10/11] mtdchar: fix offset overflow detection David Woodhouse
2013-04-15 22:35 ` Greg Kroah-Hartman
2013-04-16 8:41 ` David Woodhouse
2013-04-22 1:22 ` Ben Hutchings
2013-04-15 2:17 ` [ 11/11] r8169: fix auto speed down issue Greg Kroah-Hartman
2013-04-15 14:03 ` [ 00/11] 3.0.74-stable review Shuah Khan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130415020614.846683113@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=ben@decadent.org.uk \
--cc=dedekind1@gmail.com \
--cc=dwmw2@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=spender@grsecurity.net \
--cc=stable@vger.kernel.org \
--cc=suresh.b.siddha@intel.com \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).