Commit 48a6c2a9 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: fix for massive OF properties

From: Anton Blanchard <anton@samba.org>

We have some versions of firmware out there that have huge OF properties.
So huge that we end up overwriting our initrd.

Place a 1MB limit and warn bitterly if its over this.  Also fix a use of
package-to-path where the variable was 64bytes but we would pass in a
length of 255.
parent 3680d636
...@@ -60,6 +60,14 @@ ...@@ -60,6 +60,14 @@
extern const struct linux_logo logo_linux_clut224; extern const struct linux_logo logo_linux_clut224;
#endif #endif
/*
* Properties whose value is longer than this get excluded from our
* copy of the device tree. This value does need to be big enough to
* ensure that we don't lose things like the interrupt-map property
* on a PCI-PCI bridge.
*/
#define MAX_PROPERTY_LENGTH (1UL * 1024 * 1024)
/* /*
* prom_init() is called very early on, before the kernel text * prom_init() is called very early on, before the kernel text
* and data have been mapped to KERNELBASE. At this point the code * and data have been mapped to KERNELBASE. At this point the code
...@@ -908,9 +916,11 @@ prom_initialize_tce_table(void) ...@@ -908,9 +916,11 @@ prom_initialize_tce_table(void)
*tce_entryp = tce_entry; *tce_entryp = tce_entry;
} }
/* It seems OF doesn't null-terminate the path :-( */
memset(path, 0, sizeof(path));
/* Call OF to setup the TCE hardware */ /* Call OF to setup the TCE hardware */
if (call_prom(RELOC("package-to-path"), 3, 1, node, if (call_prom(RELOC("package-to-path"), 3, 1, node,
path, 255) <= 0) { path, sizeof(path)-1) <= 0) {
prom_print(RELOC("package-to-path failed\n")); prom_print(RELOC("package-to-path failed\n"));
} else { } else {
prom_print(RELOC("opened ")); prom_print(RELOC("opened "));
...@@ -1687,6 +1697,11 @@ check_display(unsigned long mem) ...@@ -1687,6 +1697,11 @@ check_display(unsigned long mem)
/* It seems OF doesn't null-terminate the path :-( */ /* It seems OF doesn't null-terminate the path :-( */
path = (char *) mem; path = (char *) mem;
memset(path, 0, 256); memset(path, 0, 256);
/*
* leave some room at the end of the path for appending extra
* arguments
*/
if ((long) call_prom(RELOC("package-to-path"), 3, 1, if ((long) call_prom(RELOC("package-to-path"), 3, 1,
node, path, 250) < 0) node, path, 250) < 0)
continue; continue;
...@@ -1794,8 +1809,7 @@ copy_device_tree(unsigned long mem_start) ...@@ -1794,8 +1809,7 @@ copy_device_tree(unsigned long mem_start)
return new_start; return new_start;
} }
__init static unsigned long __init
static unsigned long
inspect_node(phandle node, struct device_node *dad, inspect_node(phandle node, struct device_node *dad,
unsigned long mem_start, unsigned long mem_end, unsigned long mem_start, unsigned long mem_end,
struct device_node ***allnextpp) struct device_node ***allnextpp)
...@@ -1843,6 +1857,22 @@ inspect_node(phandle node, struct device_node *dad, ...@@ -1843,6 +1857,22 @@ inspect_node(phandle node, struct device_node *dad,
valp, mem_end - mem_start); valp, mem_end - mem_start);
if (pp->length < 0) if (pp->length < 0)
continue; continue;
if (pp->length > MAX_PROPERTY_LENGTH) {
char path[128];
prom_print(RELOC("WARNING: ignoring large property "));
/* It seems OF doesn't null-terminate the path :-( */
memset(path, 0, sizeof(path));
if (call_prom(RELOC("package-to-path"), 3, 1, node,
path, sizeof(path)-1) > 0)
prom_print(path);
prom_print(namep);
prom_print(RELOC(" length 0x"));
prom_print_hex(pp->length);
prom_print_nl();
continue;
}
mem_start = DOUBLEWORD_ALIGN(mem_start + pp->length); mem_start = DOUBLEWORD_ALIGN(mem_start + pp->length);
*prev_propp = PTRUNRELOC(pp); *prev_propp = PTRUNRELOC(pp);
prev_propp = &pp->next; prev_propp = &pp->next;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment