Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
7890ba8c
Commit
7890ba8c
authored
Jan 19, 2009
by
Ingo Molnar
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'stackprotector' into core/percpu
parents
99937d64
b2b062b8
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
134 additions
and
31 deletions
+134
-31
arch/x86/Kconfig
arch/x86/Kconfig
+10
-13
arch/x86/Kconfig.debug
arch/x86/Kconfig.debug
+1
-0
arch/x86/Makefile
arch/x86/Makefile
+1
-1
arch/x86/include/asm/pda.h
arch/x86/include/asm/pda.h
+2
-2
arch/x86/include/asm/stackprotector.h
arch/x86/include/asm/stackprotector.h
+39
-0
arch/x86/include/asm/system.h
arch/x86/include/asm/system.h
+5
-1
arch/x86/kernel/Makefile
arch/x86/kernel/Makefile
+1
-0
arch/x86/kernel/process_64.c
arch/x86/kernel/process_64.c
+12
-1
arch/x86/mm/fault.c
arch/x86/mm/fault.c
+7
-0
include/linux/magic.h
include/linux/magic.h
+1
-0
include/linux/sched.h
include/linux/sched.h
+14
-2
include/linux/stackprotector.h
include/linux/stackprotector.h
+16
-0
init/main.c
init/main.c
+7
-0
kernel/exit.c
kernel/exit.c
+1
-4
kernel/fork.c
kernel/fork.c
+5
-0
kernel/panic.c
kernel/panic.c
+11
-1
kernel/sched.c
kernel/sched.c
+1
-6
No files found.
arch/x86/Kconfig
View file @
7890ba8c
...
...
@@ -1340,13 +1340,17 @@ config SECCOMP
If unsure, say Y. Only embedded should say N here.
config CC_STACKPROTECTOR_ALL
bool
config CC_STACKPROTECTOR
bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
depends on X86_64 && EXPERIMENTAL && BROKEN
depends on X86_64
select CC_STACKPROTECTOR_ALL
help
This option turns on the -fstack-protector GCC feature. This
feature puts, at the beginning of
critical functions, a canary
value on
the stack just before the return address, and validates
This option turns on the -fstack-protector GCC feature. This
feature puts, at the beginning of
functions, a canary value on
the stack just before the return address, and validates
the value just before actually returning. Stack based buffer
overflows (that need to overwrite this return address) now also
overwrite the canary, which gets detected and the attack is then
...
...
@@ -1354,15 +1358,8 @@ config CC_STACKPROTECTOR
This feature requires gcc version 4.2 or above, or a distribution
gcc with the feature backported. Older versions are automatically
detected and for those versions, this configuration option is ignored.
config CC_STACKPROTECTOR_ALL
bool "Use stack-protector for all functions"
depends on CC_STACKPROTECTOR
help
Normally, GCC only inserts the canary value protection for
functions that use large-ish on-stack buffers. By enabling
this option, GCC will be asked to do this for ALL functions.
detected and for those versions, this configuration option is
ignored. (and a warning is printed during bootup)
source kernel/Kconfig.hz
...
...
arch/x86/Kconfig.debug
View file @
7890ba8c
...
...
@@ -117,6 +117,7 @@ config DEBUG_RODATA
config DEBUG_RODATA_TEST
bool "Testcase for the DEBUG_RODATA feature"
depends on DEBUG_RODATA
default y
help
This option enables a testcase for the DEBUG_RODATA
feature as well as for the change_page_attr() infrastructure.
...
...
arch/x86/Makefile
View file @
7890ba8c
...
...
@@ -73,7 +73,7 @@ else
stackp
:=
$(CONFIG_SHELL)
$(srctree)
/scripts/gcc-x86_64-has-stack-protector.sh
stackp-$(CONFIG_CC_STACKPROTECTOR)
:=
$(
shell
$(stackp)
\
"
$(CC)
"
-fstack-protector
)
"
$(CC)
"
"-fstack-protector -DGCC_HAS_SP"
)
stackp-$(CONFIG_CC_STACKPROTECTOR_ALL)
+=
$(
shell
$(stackp)
\
"
$(CC)
"
-fstack-protector-all
)
...
...
arch/x86/include/asm/pda.h
View file @
7890ba8c
...
...
@@ -17,11 +17,9 @@ struct x8664_pda {
unsigned
long
unused4
;
int
unused5
;
unsigned
int
unused6
;
/* 36 was cpunumber */
#ifdef CONFIG_CC_STACKPROTECTOR
unsigned
long
stack_canary
;
/* 40 stack canary value */
/* gcc-ABI: this canary MUST be at
offset 40!!! */
#endif
short
in_bootmem
;
/* pda lives in bootmem */
}
____cacheline_aligned_in_smp
;
...
...
@@ -42,4 +40,6 @@ extern void pda_init(int);
#endif
#define refresh_stack_canary() write_pda(stack_canary, current->stack_canary)
#endif
/* _ASM_X86_PDA_H */
arch/x86/include/asm/stackprotector.h
0 → 100644
View file @
7890ba8c
#ifndef _ASM_STACKPROTECTOR_H
#define _ASM_STACKPROTECTOR_H 1
#include <asm/tsc.h>
#include <asm/pda.h>
/*
* Initialize the stackprotector canary value.
*
* NOTE: this must only be called from functions that never return,
* and it must always be inlined.
*/
static
__always_inline
void
boot_init_stack_canary
(
void
)
{
u64
canary
;
u64
tsc
;
/*
* If we're the non-boot CPU, nothing set the PDA stack
* canary up for us - and if we are the boot CPU we have
* a 0 stack canary. This is a good place for updating
* it, as we wont ever return from this function (so the
* invalid canaries already on the stack wont ever
* trigger).
*
* We both use the random pool and the current TSC as a source
* of randomness. The TSC only matters for very early init,
* there it already has some randomness on most systems. Later
* on during the bootup the random pool has true entropy too.
*/
get_random_bytes
(
&
canary
,
sizeof
(
canary
));
tsc
=
__native_read_tsc
();
canary
+=
tsc
+
(
tsc
<<
32UL
);
current
->
stack_canary
=
canary
;
write_pda
(
stack_canary
,
canary
);
}
#endif
arch/x86/include/asm/system.h
View file @
7890ba8c
...
...
@@ -95,6 +95,8 @@ do { \
".globl thread_return\n" \
"thread_return:\n\t" \
"movq "__percpu_arg([current_task])",%%rsi\n\t" \
"movq %P[task_canary](%%rsi),%%r8\n\t" \
"movq %%r8,%%gs:%P[pda_canary]\n\t" \
"movq %P[thread_info](%%rsi),%%r8\n\t" \
LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
"movq %%rax,%%rdi\n\t" \
...
...
@@ -106,7 +108,9 @@ do { \
[ti_flags] "i" (offsetof(struct thread_info, flags)), \
[tif_fork] "i" (TIF_FORK), \
[thread_info] "i" (offsetof(struct task_struct, stack)), \
[current_task] "m" (per_cpu_var(current_task)) \
[task_canary] "i" (offsetof(struct task_struct, stack_canary)),\
[current_task] "m" (per_cpu_var(current_task)), \
[pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\
: "memory", "cc" __EXTRA_CLOBBER)
#endif
...
...
arch/x86/kernel/Makefile
View file @
7890ba8c
...
...
@@ -23,6 +23,7 @@ nostackp := $(call cc-option, -fno-stack-protector)
CFLAGS_vsyscall_64.o
:=
$(PROFILING)
-g0
$(nostackp)
CFLAGS_hpet.o
:=
$(nostackp)
CFLAGS_tsc.o
:=
$(nostackp)
CFLAGS_paravirt.o
:=
$(nostackp)
obj-y
:=
process_
$(BITS)
.o signal.o entry_
$(BITS)
.o
obj-y
+=
traps.o irq.o irq_
$(BITS)
.o dumpstack_
$(BITS)
.o
...
...
arch/x86/kernel/process_64.c
View file @
7890ba8c
...
...
@@ -16,6 +16,7 @@
#include <stdarg.h>
#include <linux/stackprotector.h>
#include <linux/cpu.h>
#include <linux/errno.h>
#include <linux/sched.h>
...
...
@@ -117,6 +118,17 @@ static inline void play_dead(void)
void
cpu_idle
(
void
)
{
current_thread_info
()
->
status
|=
TS_POLLING
;
/*
* If we're the non-boot CPU, nothing set the PDA stack
* canary up for us - and if we are the boot CPU we have
* a 0 stack canary. This is a good place for updating
* it, as we wont ever return from this function (so the
* invalid canaries already on the stack wont ever
* trigger):
*/
boot_init_stack_canary
();
/* endless idle loop with no priority at all */
while
(
1
)
{
tick_nohz_stop_sched_tick
(
1
);
...
...
@@ -627,7 +639,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
(
unsigned
long
)
task_stack_page
(
next_p
)
+
THREAD_SIZE
-
KERNEL_STACK_OFFSET
);
#ifdef CONFIG_CC_STACKPROTECTOR
write_pda
(
stack_canary
,
next_p
->
stack_canary
);
/*
* Build time only check to make sure the stack_canary is at
* offset 40 in the pda; this is a gcc ABI requirement
...
...
arch/x86/mm/fault.c
View file @
7890ba8c
...
...
@@ -26,6 +26,7 @@
#include <linux/kprobes.h>
#include <linux/uaccess.h>
#include <linux/kdebug.h>
#include <linux/magic.h>
#include <asm/system.h>
#include <asm/desc.h>
...
...
@@ -589,6 +590,8 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
unsigned
long
address
;
int
write
,
si_code
;
int
fault
;
unsigned
long
*
stackend
;
#ifdef CONFIG_X86_64
unsigned
long
flags
;
int
sig
;
...
...
@@ -841,6 +844,10 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
show_fault_oops
(
regs
,
error_code
,
address
);
stackend
=
end_of_stack
(
tsk
);
if
(
*
stackend
!=
STACK_END_MAGIC
)
printk
(
KERN_ALERT
"Thread overran stack, or stack corrupted
\n
"
);
tsk
->
thread
.
cr2
=
address
;
tsk
->
thread
.
trap_no
=
14
;
tsk
->
thread
.
error_code
=
error_code
;
...
...
include/linux/magic.h
View file @
7890ba8c
...
...
@@ -47,4 +47,5 @@
#define FUTEXFS_SUPER_MAGIC 0xBAD1DEA
#define INOTIFYFS_SUPER_MAGIC 0x2BAD1DEA
#define STACK_END_MAGIC 0x57AC6E9D
#endif
/* __LINUX_MAGIC_H__ */
include/linux/sched.h
View file @
7890ba8c
...
...
@@ -1157,10 +1157,9 @@ struct task_struct {
pid_t
pid
;
pid_t
tgid
;
#ifdef CONFIG_CC_STACKPROTECTOR
/* Canary value for the -fstack-protector gcc feature */
unsigned
long
stack_canary
;
#endif
/*
* pointers to (original) parent process, youngest child, younger sibling,
* older sibling, respectively. (p->father can be replaced with
...
...
@@ -2066,6 +2065,19 @@ static inline int object_is_on_stack(void *obj)
extern
void
thread_info_cache_init
(
void
);
#ifdef CONFIG_DEBUG_STACK_USAGE
static
inline
unsigned
long
stack_not_used
(
struct
task_struct
*
p
)
{
unsigned
long
*
n
=
end_of_stack
(
p
);
do
{
/* Skip over canary */
n
++
;
}
while
(
!*
n
);
return
(
unsigned
long
)
n
-
(
unsigned
long
)
end_of_stack
(
p
);
}
#endif
/* set thread flags in other task's structures
* - see asm/thread_info.h for TIF_xxxx flags available
*/
...
...
include/linux/stackprotector.h
0 → 100644
View file @
7890ba8c
#ifndef _LINUX_STACKPROTECTOR_H
#define _LINUX_STACKPROTECTOR_H 1
#include <linux/compiler.h>
#include <linux/sched.h>
#include <linux/random.h>
#ifdef CONFIG_CC_STACKPROTECTOR
# include <asm/stackprotector.h>
#else
static
inline
void
boot_init_stack_canary
(
void
)
{
}
#endif
#endif
init/main.c
View file @
7890ba8c
...
...
@@ -14,6 +14,7 @@
#include <linux/proc_fs.h>
#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/stackprotector.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/delay.h>
...
...
@@ -539,6 +540,12 @@ asmlinkage void __init start_kernel(void)
*/
lockdep_init
();
debug_objects_early_init
();
/*
* Set up the the initial canary ASAP:
*/
boot_init_stack_canary
();
cgroup_init_early
();
local_irq_disable
();
...
...
kernel/exit.c
View file @
7890ba8c
...
...
@@ -977,12 +977,9 @@ static void check_stack_usage(void)
{
static
DEFINE_SPINLOCK
(
low_water_lock
);
static
int
lowest_to_date
=
THREAD_SIZE
;
unsigned
long
*
n
=
end_of_stack
(
current
);
unsigned
long
free
;
while
(
*
n
==
0
)
n
++
;
free
=
(
unsigned
long
)
n
-
(
unsigned
long
)
end_of_stack
(
current
);
free
=
stack_not_used
(
current
);
if
(
free
>=
lowest_to_date
)
return
;
...
...
kernel/fork.c
View file @
7890ba8c
...
...
@@ -61,6 +61,7 @@
#include <linux/proc_fs.h>
#include <linux/blkdev.h>
#include <trace/sched.h>
#include <linux/magic.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
...
...
@@ -212,6 +213,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
{
struct
task_struct
*
tsk
;
struct
thread_info
*
ti
;
unsigned
long
*
stackend
;
int
err
;
prepare_to_copy
(
orig
);
...
...
@@ -237,6 +240,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
goto
out
;
setup_thread_stack
(
tsk
,
orig
);
stackend
=
end_of_stack
(
tsk
);
*
stackend
=
STACK_END_MAGIC
;
/* for overflow detection */
#ifdef CONFIG_CC_STACKPROTECTOR
tsk
->
stack_canary
=
get_random_int
();
...
...
kernel/panic.c
View file @
7890ba8c
...
...
@@ -74,6 +74,9 @@ NORET_TYPE void panic(const char * fmt, ...)
vsnprintf
(
buf
,
sizeof
(
buf
),
fmt
,
args
);
va_end
(
args
);
printk
(
KERN_EMERG
"Kernel panic - not syncing: %s
\n
"
,
buf
);
#ifdef CONFIG_DEBUG_BUGVERBOSE
dump_stack
();
#endif
bust_spinlocks
(
0
);
/*
...
...
@@ -355,15 +358,22 @@ EXPORT_SYMBOL(warn_slowpath);
#endif
#ifdef CONFIG_CC_STACKPROTECTOR
#ifndef GCC_HAS_SP
#warning You have selected the CONFIG_CC_STACKPROTECTOR option, but the gcc used does not support this.
#endif
/*
* Called when gcc's -fstack-protector feature is used, and
* gcc detects corruption of the on-stack canary value
*/
void
__stack_chk_fail
(
void
)
{
panic
(
"stack-protector: Kernel stack is corrupted"
);
panic
(
"stack-protector: Kernel stack is corrupted in: %p
\n
"
,
__builtin_return_address
(
0
));
}
EXPORT_SYMBOL
(
__stack_chk_fail
);
#endif
core_param
(
panic
,
panic_timeout
,
int
,
0644
);
...
...
kernel/sched.c
View file @
7890ba8c
...
...
@@ -5939,12 +5939,7 @@ void sched_show_task(struct task_struct *p)
printk
(
KERN_CONT
" %016lx "
,
thread_saved_pc
(
p
));
#endif
#ifdef CONFIG_DEBUG_STACK_USAGE
{
unsigned
long
*
n
=
end_of_stack
(
p
);
while
(
!*
n
)
n
++
;
free
=
(
unsigned
long
)
n
-
(
unsigned
long
)
end_of_stack
(
p
);
}
free
=
stack_not_used
(
p
);
#endif
printk
(
KERN_CONT
"%5lu %5d %6d
\n
"
,
free
,
task_pid_nr
(
p
),
task_pid_nr
(
p
->
real_parent
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment