From: Greg Kroah-Hartman Date: Wed, 16 Oct 2013 17:41:16 +0000 (-0700) Subject: 3.11-stable patches X-Git-Tag: v3.10.17~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0aa83315e6faafac851d05aa719b5e2afe82ab92;p=thirdparty%2Fkernel%2Fstable-queue.git 3.11-stable patches added patches: x86-avoid-remapping-data-in-parse_setup_data.patch --- diff --git a/queue-3.11/series b/queue-3.11/series index 76434158bb5..60378717a5c 100644 --- a/queue-3.11/series +++ b/queue-3.11/series @@ -47,3 +47,4 @@ ipc-drop-ipc_lock_check.patch ipc-sem.c-optimize-sem_lock.patch ipc-sem.c-synchronize-the-proc-interface.patch ipc-sem.c-update-sem_otime-for-all-operations.patch +x86-avoid-remapping-data-in-parse_setup_data.patch diff --git a/queue-3.11/x86-avoid-remapping-data-in-parse_setup_data.patch b/queue-3.11/x86-avoid-remapping-data-in-parse_setup_data.patch new file mode 100644 index 00000000000..3f8d054fe79 --- /dev/null +++ b/queue-3.11/x86-avoid-remapping-data-in-parse_setup_data.patch @@ -0,0 +1,109 @@ +From 30e46b574a1db7d14404e52dca8e1aa5f5155fd2 Mon Sep 17 00:00:00 2001 +From: Linn Crosetto +Date: Tue, 13 Aug 2013 15:46:41 -0600 +Subject: x86: avoid remapping data in parse_setup_data() + +From: Linn Crosetto + +commit 30e46b574a1db7d14404e52dca8e1aa5f5155fd2 upstream. + +Type SETUP_PCI, added by setup_efi_pci(), may advertise a ROM size +larger than early_memremap() is able to handle, which is currently +limited to 256kB. If this occurs it leads to a NULL dereference in +parse_setup_data(). + +To avoid this, remap the setup_data header and allow parsing functions +for individual types to handle their own data remapping. + +Signed-off-by: Linn Crosetto +Link: http://lkml.kernel.org/r/1376430401-67445-1-git-send-email-linn@hp.com +Acked-by: Yinghai Lu +Reviewed-by: Pekka Enberg +Signed-off-by: H. Peter Anvin +Cc: Paul Gortmaker +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/e820.h | 2 +- + arch/x86/kernel/e820.c | 5 ++++- + arch/x86/kernel/setup.c | 19 ++++++++----------- + 3 files changed, 13 insertions(+), 13 deletions(-) + +--- a/arch/x86/include/asm/e820.h ++++ b/arch/x86/include/asm/e820.h +@@ -29,7 +29,7 @@ extern void e820_setup_gap(void); + extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize, + unsigned long start_addr, unsigned long long end_addr); + struct setup_data; +-extern void parse_e820_ext(struct setup_data *data); ++extern void parse_e820_ext(u64 phys_addr, u32 data_len); + + #if defined(CONFIG_X86_64) || \ + (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION)) +--- a/arch/x86/kernel/e820.c ++++ b/arch/x86/kernel/e820.c +@@ -658,15 +658,18 @@ __init void e820_setup_gap(void) + * boot_params.e820_map, others are passed via SETUP_E820_EXT node of + * linked list of struct setup_data, which is parsed here. + */ +-void __init parse_e820_ext(struct setup_data *sdata) ++void __init parse_e820_ext(u64 phys_addr, u32 data_len) + { + int entries; + struct e820entry *extmap; ++ struct setup_data *sdata; + ++ sdata = early_memremap(phys_addr, data_len); + entries = sdata->len / sizeof(struct e820entry); + extmap = (struct e820entry *)(sdata->data); + __append_e820_map(extmap, entries); + sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); ++ early_iounmap(sdata, data_len); + printk(KERN_INFO "e820: extended physical RAM map:\n"); + e820_print_map("extended"); + } +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -426,25 +426,23 @@ static void __init reserve_initrd(void) + static void __init parse_setup_data(void) + { + struct setup_data *data; +- u64 pa_data; ++ u64 pa_data, pa_next; + + pa_data = boot_params.hdr.setup_data; + while (pa_data) { +- u32 data_len, map_len; ++ u32 data_len, map_len, data_type; + + map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK), + (u64)sizeof(struct setup_data)); + data = early_memremap(pa_data, map_len); + data_len = data->len + sizeof(struct setup_data); +- if (data_len > map_len) { +- early_iounmap(data, map_len); +- data = early_memremap(pa_data, data_len); +- map_len = data_len; +- } ++ data_type = data->type; ++ pa_next = data->next; ++ early_iounmap(data, map_len); + +- switch (data->type) { ++ switch (data_type) { + case SETUP_E820_EXT: +- parse_e820_ext(data); ++ parse_e820_ext(pa_data, data_len); + break; + case SETUP_DTB: + add_dtb(pa_data); +@@ -452,8 +450,7 @@ static void __init parse_setup_data(void + default: + break; + } +- pa_data = data->next; +- early_iounmap(data, map_len); ++ pa_data = pa_next; + } + } +