Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 1797

kernel-2.6.18-194.11.1.el5.src.rpm

From: Larry Woodman <lwoodman@redhat.com>
Date: Tue, 15 Jul 2008 14:01:27 -0400
Subject: [mm] check physical address range in ioremap
Message-id: 1216144887.13816.13.camel@localhost.localdomain
O-Subject: [RHEL5-U3 patch] 2.6.26 backport of "check physical address range in ioremap" into RHEL5-U3
Bugzilla: 455478

The attached patch is a backport from 2.6.26 to RHEL5-U3.

Fixes BZ 455478

Gitweb:
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=e3100c82abd9aa643dc15828202aceeae3504e03
Commit:     e3100c82abd9aa643dc15828202aceeae3504e03
Parent:     b8c2d3dfbc117dff26058fbac316b8acfc2cb5f7
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Wed Feb 27 20:57:40 2008 +0100
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Thu Apr 17 17:40:51 2008 +0200

    x86: check physical address range in ioremap

    Roland Dreier reported in http://lkml.org/lkml/2008/2/27/194

    [ 8425.915139] BUG: unable to handle kernel paging request at
ffffc20001a0a000
    [ 8425.919087] IP: [<ffffffff8021dacc>] clflush_cache_range+0xc/0x25
    [ 8425.919087] PGD 1bf80e067 PUD 1bf80f067 PMD 1bb497067 PTE
80000047000ee17b

    This is on a Intel machine with 36bit physical address space. The
PTE
    entry references 47000ee000, which is outside of it.

    Add a check for the physical address space and warn/printk about the
    stupid caller.

    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
index 45d7d82..024efc9 100644
--- a/arch/x86_64/mm/ioremap.c
+++ b/arch/x86_64/mm/ioremap.c
@@ -22,6 +22,11 @@
 #define ISA_START_ADDRESS      0xa0000
 #define ISA_END_ADDRESS                0x100000
 
+static inline int phys_addr_valid(unsigned long addr)
+{
+	return addr < (1UL << boot_cpu_data.x86_phys_bits);
+}
+
 static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
 	unsigned long phys_addr, unsigned long flags)
 {
@@ -171,6 +176,13 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
 	if (!size || last_addr < phys_addr)
 		return NULL;
 
+	if (!phys_addr_valid(phys_addr)) {
+		printk(KERN_WARNING "ioremap: invalid physical address %lx\n",
+			phys_addr);
+		WARN_ON_ONCE(1);
+		return NULL;
+	}
+
 	/*
 	 * Don't remap the low PCI/ISA area, it's always mapped..
 	 */