[FAQ14383]如何在内核打开栈保护功能?

来源:互联网 发布:淘宝美妆 编辑:程序博客网 时间:2024/05/22 13:45
[DESCRIPTION]
内存踩坏一般都很难排查问题,需要借助各种调试方法找出问题点。不同的内存踩坏有不同的调试方法,这里介绍下内存踩坏中的一种:栈帧溢出。
栈帧溢出是指:在某个函数内踩坏了不属于该函数的栈帧。举例:
[C/C++]hide
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 voida(void)
 
{
 
   intb[3], inti;
 
 
 
   for(i = 0; i <= 3; i++) {
 
        b[i] = 0;
 
   }
 
}
这里b只有3个int长度,但是却循环4次,将不属于b的内存踩坏,而b在a函数的栈帧里,这种情形叫栈帧溢出。
针对这种的调试方法需要借助gcc编译器的功能:stack-protector。原理是在函数栈帧前埋一个守卫,在函数退出时检查该守卫是否被踩坏,如果有则发生了栈帧溢出。
守卫的值会从__stack_chk_guard里获取,检查失败会调用__stack_chk_fail()函数。详情请搜索GCC说明文档。
这种方法虽然无法100%抓到问题点,但绝对是非常有效的防护措施,以下介绍打开方法。
 
[SOLUTION]
ARM32 AOSP版本
1. 在alps/kernel-3.10/arch/arm/configs/$proj_defconfig或alps/kernel-3.10/arch/arm/configs/$proj_debug_defconfig
将:
# CONFIG_CC_STACKPROTECTOR is not set
修改为:
CONFIG_CC_STACKPROTECTOR=y
 
2. 在alps/kernel-3.10/arch/arm/Makefile

ifeq ($(CONFIG_CC_STACKPROTECTOR),y)
KBUILD_CFLAGS+=-fstack-protector
endif
修改为:
ifeq ($(CONFIG_CC_STACKPROTECTOR),y)
KBUILD_CFLAGS+=-fstack-protector-all
endif
 
3. 在alps/kernel-3.10/arch/arm/boot/compressed/Makefile添加:
ifeq ($(CONFIG_CC_STACKPROTECTOR),y)
ORIG_CFLAGS := $(KBUILD_CFLAGS)
KBUILD_CFLAGS = $(subst -fstack-protector-all, , $(ORIG_CFLAGS))
endif
 
ARM64 AOSP版本
ARM64版本暂不支持该功能,因此需要自己添加代码:
1. 在alps/kernel-3.10/kernel/panic.c

#ifdef CONFIG_CC_STACKPROTECTOR
修改为
#if 1
const unsigned long __stack_chk_guard __read_mostly = 0xA5A5A5A5A5A5A5A5;
EXPORT_SYMBOL(__stack_chk_guard);
 
2. 在kernel-3.10/Makefile

ifndef CONFIG_CC_STACKPROTECTOR
KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
endif
修改为:
KBUILD_CFLAGS += -fstack-protector-all
0 0
原创粉丝点击