Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
7890ba8c
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
7890ba8c
编写于
1月 19, 2009
作者:
I
Ingo Molnar
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'stackprotector' into core/percpu
上级
99937d64
b2b062b8
变更
17
隐藏空白更改
内联
并排
Showing
17 changed file
with
134 addition
and
31 deletion
+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
未找到文件。
arch/x86/Kconfig
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
));
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录