2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* misc.c
|
|
|
|
*
|
|
|
|
* This is a collection of several routines from gzip-1.0.3
|
|
|
|
* adapted for Linux.
|
|
|
|
*
|
|
|
|
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
|
|
|
|
*
|
|
|
|
* Modified for ARM Linux by Russell King
|
|
|
|
*
|
|
|
|
* Nicolas Pitre <nico@visuaide.com> 1999/04/14 :
|
|
|
|
* For this code to run directly from Flash, all constant variables must
|
|
|
|
* be marked with 'const' and all other variables initialized at run-time
|
|
|
|
* only. This way all non constant variables will end up in the bss segment,
|
|
|
|
* which should point to addresses in RAM and cleared to 0 on start.
|
|
|
|
* This allows for a much quicker boot time.
|
|
|
|
*/
|
|
|
|
|
|
|
|
unsigned int __machine_arch_type;
|
|
|
|
|
2009-03-31 19:05:35 +00:00
|
|
|
#include <linux/compiler.h> /* for inline */
|
2011-09-14 01:42:55 +00:00
|
|
|
#include <linux/types.h>
|
2010-01-08 22:42:43 +00:00
|
|
|
#include <linux/linkage.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2006-03-28 09:24:33 +00:00
|
|
|
static void putstr(const char *ptr);
|
2010-03-10 18:10:28 +00:00
|
|
|
extern void error(char *x);
|
2006-03-28 09:24:33 +00:00
|
|
|
|
2013-03-14 07:47:27 +00:00
|
|
|
#include CONFIG_UNCOMPRESS_INCLUDE
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2006-03-28 09:24:33 +00:00
|
|
|
#ifdef CONFIG_DEBUG_ICEDCC
|
2006-09-20 12:03:34 +00:00
|
|
|
|
2011-03-23 21:46:15 +00:00
|
|
|
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
|
2006-09-20 12:03:34 +00:00
|
|
|
|
|
|
|
static void icedcc_putc(int ch)
|
|
|
|
{
|
|
|
|
int status, i = 0x4000000;
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (--i < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
asm volatile ("mrc p14, 0, %0, c0, c1, 0" : "=r" (status));
|
|
|
|
} while (status & (1 << 29));
|
|
|
|
|
|
|
|
asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
|
|
|
|
}
|
2010-01-19 15:40:07 +00:00
|
|
|
|
|
|
|
|
2009-02-25 03:20:40 +00:00
|
|
|
#elif defined(CONFIG_CPU_XSCALE)
|
|
|
|
|
|
|
|
static void icedcc_putc(int ch)
|
|
|
|
{
|
|
|
|
int status, i = 0x4000000;
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (--i < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
asm volatile ("mrc p14, 0, %0, c14, c0, 0" : "=r" (status));
|
|
|
|
} while (status & (1 << 28));
|
|
|
|
|
|
|
|
asm("mcr p14, 0, %0, c8, c0, 0" : : "r" (ch));
|
|
|
|
}
|
2006-09-20 12:03:34 +00:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
2006-03-28 09:34:05 +00:00
|
|
|
static void icedcc_putc(int ch)
|
|
|
|
{
|
|
|
|
int status, i = 0x4000000;
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (--i < 0)
|
|
|
|
return;
|
|
|
|
|
2006-05-02 19:40:56 +00:00
|
|
|
asm volatile ("mrc p14, 0, %0, c0, c0, 0" : "=r" (status));
|
2006-03-28 09:34:05 +00:00
|
|
|
} while (status & 2);
|
|
|
|
|
2006-05-02 19:40:56 +00:00
|
|
|
asm("mcr p14, 0, %0, c1, c0, 0" : : "r" (ch));
|
2006-03-28 09:34:05 +00:00
|
|
|
}
|
|
|
|
|
2006-09-20 12:03:34 +00:00
|
|
|
#endif
|
|
|
|
|
2006-03-28 09:24:33 +00:00
|
|
|
#define putc(ch) icedcc_putc(ch)
|
|
|
|
#endif
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2006-03-28 09:24:33 +00:00
|
|
|
static void putstr(const char *ptr)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2006-03-28 09:24:33 +00:00
|
|
|
char c;
|
|
|
|
|
|
|
|
while ((c = *ptr++) != '\0') {
|
|
|
|
if (c == '\n')
|
|
|
|
putc('\r');
|
|
|
|
putc(c);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
2006-03-28 09:24:33 +00:00
|
|
|
|
|
|
|
flush();
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2011-04-19 20:13:23 +00:00
|
|
|
* gzip declarations
|
2005-04-16 22:20:36 +00:00
|
|
|
*/
|
|
|
|
extern char input_data[];
|
|
|
|
extern char input_data_end[];
|
|
|
|
|
ARM: Eliminate decompressor -Dstatic= PIC hack
We used to build decompressors with -Dstatic= to avoid any local data
being generated. The problem is that local data generates GOTOFF
relocations, which means we can't relocate the data relative to the
text segment.
Global data, on the other hand, goes through the GOT, and can be
relocated anywhere.
Unfortunately, with the new decompressors, this presents a problem
since they declare static data within functions, and this leads to
stack overflow.
Fix this by separating out the decompressor code into a separate file,
and removing 'static' from BSS data in misc.c.
Also, discard the .data section - this means that should we end up
with read/write initialized data, the decompressor will fail to link
and the problem will be obvious.
Acked-by: Nicolas Pitre <nico@fluxnic.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2010-02-25 12:14:40 +00:00
|
|
|
unsigned char *output_data;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
ARM: Eliminate decompressor -Dstatic= PIC hack
We used to build decompressors with -Dstatic= to avoid any local data
being generated. The problem is that local data generates GOTOFF
relocations, which means we can't relocate the data relative to the
text segment.
Global data, on the other hand, goes through the GOT, and can be
relocated anywhere.
Unfortunately, with the new decompressors, this presents a problem
since they declare static data within functions, and this leads to
stack overflow.
Fix this by separating out the decompressor code into a separate file,
and removing 'static' from BSS data in misc.c.
Also, discard the .data section - this means that should we end up
with read/write initialized data, the decompressor will fail to link
and the problem will be obvious.
Acked-by: Nicolas Pitre <nico@fluxnic.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2010-02-25 12:14:40 +00:00
|
|
|
unsigned long free_mem_ptr;
|
|
|
|
unsigned long free_mem_end_ptr;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2005-11-08 22:43:05 +00:00
|
|
|
#ifndef arch_error
|
|
|
|
#define arch_error(x)
|
|
|
|
#endif
|
|
|
|
|
ARM: Eliminate decompressor -Dstatic= PIC hack
We used to build decompressors with -Dstatic= to avoid any local data
being generated. The problem is that local data generates GOTOFF
relocations, which means we can't relocate the data relative to the
text segment.
Global data, on the other hand, goes through the GOT, and can be
relocated anywhere.
Unfortunately, with the new decompressors, this presents a problem
since they declare static data within functions, and this leads to
stack overflow.
Fix this by separating out the decompressor code into a separate file,
and removing 'static' from BSS data in misc.c.
Also, discard the .data section - this means that should we end up
with read/write initialized data, the decompressor will fail to link
and the problem will be obvious.
Acked-by: Nicolas Pitre <nico@fluxnic.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2010-02-25 12:14:40 +00:00
|
|
|
void error(char *x)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2005-11-08 22:43:05 +00:00
|
|
|
arch_error(x);
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
putstr("\n\n");
|
|
|
|
putstr(x);
|
|
|
|
putstr("\n\n -- System halted");
|
|
|
|
|
|
|
|
while(1); /* Halt */
|
|
|
|
}
|
|
|
|
|
2010-01-08 22:42:43 +00:00
|
|
|
asmlinkage void __div0(void)
|
|
|
|
{
|
|
|
|
error("Attempting division by 0!");
|
|
|
|
}
|
|
|
|
|
stackprotector: Introduce CONFIG_CC_STACKPROTECTOR_STRONG
This changes the stack protector config option into a choice of
"None", "Regular", and "Strong":
CONFIG_CC_STACKPROTECTOR_NONE
CONFIG_CC_STACKPROTECTOR_REGULAR
CONFIG_CC_STACKPROTECTOR_STRONG
"Regular" means the old CONFIG_CC_STACKPROTECTOR=y option.
"Strong" is a new mode introduced by this patch. With "Strong" the
kernel is built with -fstack-protector-strong (available in
gcc 4.9 and later). This option increases the coverage of the stack
protector without the heavy performance hit of -fstack-protector-all.
For reference, the stack protector options available in gcc are:
-fstack-protector-all:
Adds the stack-canary saving prefix and stack-canary checking
suffix to _all_ function entry and exit. Results in substantial
use of stack space for saving the canary for deep stack users
(e.g. historically xfs), and measurable (though shockingly still
low) performance hit due to all the saving/checking. Really not
suitable for sane systems, and was entirely removed as an option
from the kernel many years ago.
-fstack-protector:
Adds the canary save/check to functions that define an 8
(--param=ssp-buffer-size=N, N=8 by default) or more byte local
char array. Traditionally, stack overflows happened with
string-based manipulations, so this was a way to find those
functions. Very few total functions actually get the canary; no
measurable performance or size overhead.
-fstack-protector-strong
Adds the canary for a wider set of functions, since it's not
just those with strings that have ultimately been vulnerable to
stack-busting. With this superset, more functions end up with a
canary, but it still remains small compared to all functions
with only a small change in performance. Based on the original
design document, a function gets the canary when it contains any
of:
- local variable's address used as part of the right hand side
of an assignment or function argument
- local variable is an array (or union containing an array),
regardless of array type or length
- uses register local variables
https://docs.google.com/a/google.com/document/d/1xXBH6rRZue4f296vGt9YQcuLVQHeE516stHwt8M9xyU
Find below a comparison of "size" and "objdump" output when built with
gcc-4.9 in three configurations:
- defconfig
11430641 kernel text size
36110 function bodies
- defconfig + CONFIG_CC_STACKPROTECTOR_REGULAR
11468490 kernel text size (+0.33%)
1015 of 36110 functions are stack-protected (2.81%)
- defconfig + CONFIG_CC_STACKPROTECTOR_STRONG via this patch
11692790 kernel text size (+2.24%)
7401 of 36110 functions are stack-protected (20.5%)
With -strong, ARM's compressed boot code now triggers stack
protection, so a static guard was added. Since this is only used
during decompression and was never used before, the exposure
here is very small. Once it switches to the full kernel, the
stack guard is back to normal.
Chrome OS has been using -fstack-protector-strong for its kernel
builds for the last 8 months with no problems.
Signed-off-by: Kees Cook <keescook@chromium.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Shawn Guo <shawn.guo@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-mips@linux-mips.org
Cc: linux-arch@vger.kernel.org
Link: http://lkml.kernel.org/r/1387481759-14535-3-git-send-email-keescook@chromium.org
[ Improved the changelog and descriptions some more. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2013-12-19 19:35:59 +00:00
|
|
|
unsigned long __stack_chk_guard;
|
|
|
|
|
|
|
|
void __stack_chk_guard_setup(void)
|
|
|
|
{
|
|
|
|
__stack_chk_guard = 0x000a0dff;
|
|
|
|
}
|
|
|
|
|
|
|
|
void __stack_chk_fail(void)
|
|
|
|
{
|
|
|
|
error("stack-protector: Kernel stack is corrupted\n");
|
|
|
|
}
|
|
|
|
|
2011-04-22 01:59:49 +00:00
|
|
|
extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
|
ARM: Eliminate decompressor -Dstatic= PIC hack
We used to build decompressors with -Dstatic= to avoid any local data
being generated. The problem is that local data generates GOTOFF
relocations, which means we can't relocate the data relative to the
text segment.
Global data, on the other hand, goes through the GOT, and can be
relocated anywhere.
Unfortunately, with the new decompressors, this presents a problem
since they declare static data within functions, and this leads to
stack overflow.
Fix this by separating out the decompressor code into a separate file,
and removing 'static' from BSS data in misc.c.
Also, discard the .data section - this means that should we end up
with read/write initialized data, the decompressor will fail to link
and the problem will be obvious.
Acked-by: Nicolas Pitre <nico@fluxnic.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2010-02-25 12:14:40 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2011-04-19 20:13:23 +00:00
|
|
|
void
|
2010-01-08 22:42:43 +00:00
|
|
|
decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
|
|
|
|
unsigned long free_mem_ptr_end_p,
|
|
|
|
int arch_id)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2011-04-22 01:59:49 +00:00
|
|
|
int ret;
|
2010-01-08 22:42:43 +00:00
|
|
|
|
stackprotector: Introduce CONFIG_CC_STACKPROTECTOR_STRONG
This changes the stack protector config option into a choice of
"None", "Regular", and "Strong":
CONFIG_CC_STACKPROTECTOR_NONE
CONFIG_CC_STACKPROTECTOR_REGULAR
CONFIG_CC_STACKPROTECTOR_STRONG
"Regular" means the old CONFIG_CC_STACKPROTECTOR=y option.
"Strong" is a new mode introduced by this patch. With "Strong" the
kernel is built with -fstack-protector-strong (available in
gcc 4.9 and later). This option increases the coverage of the stack
protector without the heavy performance hit of -fstack-protector-all.
For reference, the stack protector options available in gcc are:
-fstack-protector-all:
Adds the stack-canary saving prefix and stack-canary checking
suffix to _all_ function entry and exit. Results in substantial
use of stack space for saving the canary for deep stack users
(e.g. historically xfs), and measurable (though shockingly still
low) performance hit due to all the saving/checking. Really not
suitable for sane systems, and was entirely removed as an option
from the kernel many years ago.
-fstack-protector:
Adds the canary save/check to functions that define an 8
(--param=ssp-buffer-size=N, N=8 by default) or more byte local
char array. Traditionally, stack overflows happened with
string-based manipulations, so this was a way to find those
functions. Very few total functions actually get the canary; no
measurable performance or size overhead.
-fstack-protector-strong
Adds the canary for a wider set of functions, since it's not
just those with strings that have ultimately been vulnerable to
stack-busting. With this superset, more functions end up with a
canary, but it still remains small compared to all functions
with only a small change in performance. Based on the original
design document, a function gets the canary when it contains any
of:
- local variable's address used as part of the right hand side
of an assignment or function argument
- local variable is an array (or union containing an array),
regardless of array type or length
- uses register local variables
https://docs.google.com/a/google.com/document/d/1xXBH6rRZue4f296vGt9YQcuLVQHeE516stHwt8M9xyU
Find below a comparison of "size" and "objdump" output when built with
gcc-4.9 in three configurations:
- defconfig
11430641 kernel text size
36110 function bodies
- defconfig + CONFIG_CC_STACKPROTECTOR_REGULAR
11468490 kernel text size (+0.33%)
1015 of 36110 functions are stack-protected (2.81%)
- defconfig + CONFIG_CC_STACKPROTECTOR_STRONG via this patch
11692790 kernel text size (+2.24%)
7401 of 36110 functions are stack-protected (20.5%)
With -strong, ARM's compressed boot code now triggers stack
protection, so a static guard was added. Since this is only used
during decompression and was never used before, the exposure
here is very small. Once it switches to the full kernel, the
stack guard is back to normal.
Chrome OS has been using -fstack-protector-strong for its kernel
builds for the last 8 months with no problems.
Signed-off-by: Kees Cook <keescook@chromium.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Shawn Guo <shawn.guo@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-mips@linux-mips.org
Cc: linux-arch@vger.kernel.org
Link: http://lkml.kernel.org/r/1387481759-14535-3-git-send-email-keescook@chromium.org
[ Improved the changelog and descriptions some more. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2013-12-19 19:35:59 +00:00
|
|
|
__stack_chk_guard_setup();
|
|
|
|
|
2010-01-08 22:42:43 +00:00
|
|
|
output_data = (unsigned char *)output_start;
|
2005-04-16 22:20:36 +00:00
|
|
|
free_mem_ptr = free_mem_ptr_p;
|
2008-07-25 08:45:44 +00:00
|
|
|
free_mem_end_ptr = free_mem_ptr_end_p;
|
2005-04-16 22:20:36 +00:00
|
|
|
__machine_arch_type = arch_id;
|
|
|
|
|
|
|
|
arch_decomp_setup();
|
|
|
|
|
|
|
|
putstr("Uncompressing Linux...");
|
2011-04-22 01:59:49 +00:00
|
|
|
ret = do_decompress(input_data, input_data_end - input_data,
|
|
|
|
output_data, error);
|
|
|
|
if (ret)
|
|
|
|
error("decompressor returned an error");
|
|
|
|
else
|
|
|
|
putstr(" done, booting the kernel.\n");
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|