From ec0018e7457bec2f9984ee95ad4e4e689313b2c9 Mon Sep 17 00:00:00 2001 From: Justin M. Forbes Date: Feb 14 2013 17:35:13 +0000 Subject: mm: Check if PUD is large when validating a kernel address --- diff --git a/kernel.spec b/kernel.spec index 5ff8446..b176a68 100644 --- a/kernel.spec +++ b/kernel.spec @@ -769,6 +769,10 @@ Patch21253: netback-correct-netbk_tx_err-to-handle-wrap-around.patch #rhbz 906309 910848 CVE-2013-0228 Patch21254: xen-dont-assume-ds-is-usable-in-xen_iret-for-32-bit-PVOPS.patch +Patch23000: silence-brcmsmac-warning.patch + +Patch23100: validate-pud-largepage.patch + #rhbz 909591 Patch21255: usb-cypress-supertop.patch @@ -1481,6 +1485,10 @@ ApplyPatch rtlwifi-Fix-scheduling-while-atomic-bug.patch #rhbz 892811 ApplyPatch ath9k_rx_dma_stop_check.patch +ApplyPatch silence-brcmsmac-warning.patch + +ApplyPatch validate-pud-largepage.patch + #rhbz 910886 CVE-2013-0216/CVE-2013-0217 ApplyPatch xen-netback-shutdown-the-ring-if-it-contains-garbage.patch ApplyPatch xen-netback-don-t-leak-pages-on-failure-in-xen_netbk_tx_check_gop.patch @@ -2348,11 +2356,18 @@ fi # '-' | | # '-' %changelog + * Thu Feb 14 2013 Josh Boyer - Add patch to fix corruption on newer M6116 SATA bridges (rhbz 909591) - CVE-2013-0228 xen: xen_iret() invalid %ds local DoS (rhbz 910848 906309) - CVE-2013-0216/0127 xen: netback DoS via malicious guest ring (rhbz 910886) +* Tue Feb 12 2013 Dave Jones +- mm: Check if PUD is large when validating a kernel address + +* Tue Feb 12 2013 Dave Jones +- Silence brcmsmac warnings. (Fixed in 3.8, but not backporting to 3.7) + * Mon Feb 11 2013 Justin M. Forbes - 3.7.7-101 - Linux v3.7.7 diff --git a/silence-brcmsmac-warning.patch b/silence-brcmsmac-warning.patch new file mode 100644 index 0000000..b1915e9 --- /dev/null +++ b/silence-brcmsmac-warning.patch @@ -0,0 +1,14 @@ +This is fixed in 3.8, but is too much to backport for now. +As there's no point in abrt telling us this is broken, we'll just silence it. + +--- linux-3.7.7-201.fc18.x86_64/drivers/net/wireless/brcm80211/brcmsmac/main.c~ 2013-02-12 11:36:18.787973130 -0500 ++++ linux-3.7.7-201.fc18.x86_64/drivers/net/wireless/brcm80211/brcmsmac/main.c 2013-02-12 11:37:02.950969879 -0500 +@@ -7993,8 +7993,6 @@ void brcms_c_wait_for_tx_completion(stru + if (--timeout == 0) + break; + } +- +- WARN_ON_ONCE(timeout == 0); + } + + void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval) diff --git a/validate-pud-largepage.patch b/validate-pud-largepage.patch new file mode 100644 index 0000000..db67112 --- /dev/null +++ b/validate-pud-largepage.patch @@ -0,0 +1,102 @@ +Date: Mon, 11 Feb 2013 14:52:36 +0000 +From: Mel Gorman +To: Ingo Molnar , Andrew Morton +Cc: Mel Gorman , linux-kernel@vger.kernel.org, linux-mm@kvack.org +Subject: [PATCH] x86: mm: Check if PUD is large when validating a kernel address +Message-ID: <20130211145236.GX21389@suse.de> +MIME-Version: 1.0 + +A user reported the following oops when a backup process read +/proc/kcore. + + BUG: unable to handle kernel paging request at ffffbb00ff33b000 + IP: [] kern_addr_valid+0xbe/0x110 + PGD 0 + Oops: 0000 [#1] SMP + CPU 6 + Modules linked in: af_packet nfs lockd fscache auth_rpcgss nfs_acl sunrpc 8021q garp stp llc cpufreq_conservative cpufreq_userspace cpufreq_powersave acpi_cpufreq mperf microcode fuse nls_iso8859_1 nls_cp437 vfat fat loop dm_mod ioatdma ipv6 ipv6_lib igb dca i7core_edac edac_core i2c_i801 i2c_core cdc_ether usbnet bnx2 mii iTCO_wdt iTCO_vendor_support shpchp rtc_cmos pci_hotplug tpm_tis sg tpm pcspkr tpm_bios serio_raw button ext3 jbd mbcache uhci_hcd ehci_hcd usbcore sd_mod crc_t10dif usb_common processor thermal_sys hwmon scsi_dh_emc scsi_dh_rdac scsi_dh_alua scsi_dh_hp_sw scsi_dh ata_generic ata_piix libata megaraid_sas scsi_mod + + Pid: 16196, comm: Hibackp Not tainted 3.0.13-0.27-default #1 IBM System x3550 M3 -[7944 K3G]-/94Y7614 + RIP: 0010:[] [] kern_addr_valid+0xbe/0x110 + RSP: 0018:ffff88094165fe80 EFLAGS: 00010246 + RAX: 00003300ff33b000 RBX: ffff880100000000 RCX: 0000000000000000 + RDX: 0000000100000000 RSI: ffff880000000000 RDI: ff32b300ff33b400 + RBP: 0000000000001000 R08: 00003ffffffff000 R09: 0000000000000000 + R10: 22302e31223d6e6f R11: 0000000000000246 R12: 0000000000001000 + R13: 0000000000003000 R14: 0000000000571be0 R15: ffff88094165ff50 + FS: 00007ff152d33700(0000) GS:ffff88097f2c0000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b + CR2: ffffbb00ff33b000 CR3: 00000009405a3000 CR4: 00000000000006e0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 + Process Hibackp (pid: 16196, threadinfo ffff88094165e000, task ffff8808eb9ba600) + Stack: + ffffffff811b8aaa 0000000000004000 ffff880943fea480 ffff8808ef2bae50 + ffff880943d32980 fffffffffffffffb ffff8808ef2bae40 ffff88094165ff50 + 0000000000004000 000000000056ebe0 ffffffff811ad847 000000000056ebe0 + Call Trace: + [] read_kcore+0x17a/0x370 + [] proc_reg_read+0x77/0xc0 + [] vfs_read+0xc7/0x130 + [] sys_read+0x53/0xa0 + [] system_call_fastpath+0x16/0x1b + +Investigation determined that the bug triggered when reading system RAM +at the 4G mark. On this system, that was the first address using 1G pages +for the virt->phys direct mapping so the PUD is pointing to a physical +address, not a PMD page. The problem is that the page table walker in +kern_addr_valid() is not checking pud_large() and treats the physical +address as if it was a PMD. If it happens to look like pmd_none then it'll +silently fail, probably returning zeros instead of real data. If the data +happens to look like a present PMD though, it will be walked resulting in +the oops above. This patch adds the necessary pud_large() check. + +Unfortunately the problem was not readily reproducible and now they are +running the backup program without accessing /proc/kcore so the patch has +not been validated but I think it makes sense. If reviewers agree then it +should also be included in -stable back as far as 3.0-stable. + +Cc: stable@vger.kernel.org +Signed-off-by: Mel Gorman +--- + arch/x86/include/asm/pgtable.h | 5 +++++ + arch/x86/mm/init_64.c | 3 +++ + 2 files changed, 8 insertions(+) + +diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h +index 5199db2..1c1a955 100644 +--- a/arch/x86/include/asm/pgtable.h ++++ b/arch/x86/include/asm/pgtable.h +@@ -142,6 +142,11 @@ static inline unsigned long pmd_pfn(pmd_t pmd) + return (pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT; + } + ++static inline unsigned long pud_pfn(pud_t pud) ++{ ++ return (pud_val(pud) & PTE_PFN_MASK) >> PAGE_SHIFT; ++} ++ + #define pte_page(pte) pfn_to_page(pte_pfn(pte)) + + static inline int pmd_large(pmd_t pte) +diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c +index 2ead3c8..75c9a6a 100644 +--- a/arch/x86/mm/init_64.c ++++ b/arch/x86/mm/init_64.c +@@ -831,6 +831,9 @@ int kern_addr_valid(unsigned long addr) + if (pud_none(*pud)) + return 0; + ++ if (pud_large(*pud)) ++ return pfn_valid(pud_pfn(*pud)); ++ + pmd = pmd_offset(pud, addr); + if (pmd_none(*pmd)) + return 0; + +-- +To unsubscribe, send a message with 'unsubscribe linux-mm' in +the body to majordomo@kvack.org. For more info on Linux MM, +see: http://www.linux-mm.org/ . +Don't email: email@kvack.org +