浏览器大全:是一个提供流行浏览器教程、在线学习分享的学习平台!

Linux编译x86架构内核出现_stack_chk_guard未定义出错

Linux,全称GNU/Linux,是一种免费使用和自由传播的类UNIX操作系统,其内核由林纳斯·本纳第克特·托瓦兹于1991年10月5日首次发布,它主要受到Minix和Unix思想的启发,是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统。
背景
Android模拟器运行于virtualbox中,而virtualbox运行于x86架构的pc端,所以android及其Linux内核都编译成x86架构。当virtualbox的vt未开启的情况下android系统会出现各种问题,如arm库游戏不能运行,桌面平凡挂死重启。通过查看日志,都奔溃在了#00 pc 000183c6 /system/lib/libc.so (__get_thread+6)这个点。
 
问题
在android内核为3.10时选择CONFIG_CC_STACKPROTECTOR=y(开启内核栈保护功能),在x86架构下能正常编译解决vt下桌面重复挂死、arm库游戏不能玩的问题。但是如果升级android内核为3.18,内核开启栈保护功能时,交叉编译x86架构下的linux内核就会出现编译错误。具体看如下开启内核配置和出错日志:
开启3.18栈保护的内核配置选项如下:
@@ -41,7 +41,6 @@ CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_HAVE_INTEL_TXT=y
CONFIG_X86_32_SMP=y
CONFIG_X86_HT=y
-CONFIG_X86_32_LAZY_GS=y
CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-ecx -fcall-saved-edx"
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_FIX_EARLYCON_MEM=y
@@ -249,10 +248,10 @@ CONFIG_HAVE_CMPXCHG_DOUBLE=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_CC_STACKPROTECTOR=y
-# CONFIG_CC_STACKPROTECTOR is not set
-CONFIG_CC_STACKPROTECTOR_NONE=y
+CONFIG_CC_STACKPROTECTOR=y
+# CONFIG_CC_STACKPROTECTOR_NONE is not set
# CONFIG_CC_STACKPROTECTOR_REGULAR is not set
-# CONFIG_CC_STACKPROTECTOR_STRONG is not set
+CONFIG_CC_STACKPROTECTOR_STRONG=y
CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
开启3.18内核栈保护配置后内核编译x86架构错误如下:
CHK     include/generated/compile.h
UPD     include/generated/compile.h
CC      init/version.o
LD      init/built-in.o
android-4.4.4/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.6/bin/i686-linux-android-ld: init/built-in.o: in function do_one_initcall:init_task.c(.text+0x7f): error: undefined reference to '__stack_chk_guard'
android-4.4.4/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.6/bin/i686-linux-android-ld: init/built-in.o: in function do_one_initcall:init_task.c(.text+0x1c6): error: undefined reference to '__stack_chk_guard'
android-4.4.4/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.6/bin/i686-linux-android-ld: init/built-in.o: in function name_to_dev_t:init_task.c(.text+0x261): error: undefined reference to '__stack_chk_guard'
android-4.4.4/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.6/bin/i686-linux-android-ld: init/built-in.o: in function name_to_dev_t:init_task.c(.text+0x517): error: undefined reference to '__stack_chk_guard'
make: *** [vmlinux] Error 1
arch/x86/Makefile:116: stack-protector enabled but compiler support broken
 
分析解决
上述error: undefined reference to '__stack_chk_guard'错误通过各种google也没有找到正解,有的说是gcc需要4.9及以上,然而用交叉编译工具4.9也不行。还查看了android源码关于stack protector的相关修复,都没有啥卵用。最后通过查看__stack_chk_guard字段发现,x86架构没有定义此字段,而sh,arm,mips等架构确定义了。在穷途末路时只能自己动手依葫芦画瓢,期待有所进展。如下patch为本人添加,不仅能解决编译错误,还确实解决了vt未开启时,virtualbox下运行android镜像出现的各种问题。
Linux编译x86架构时__stack_chk_guard未定义错误的修复patch
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h
index 6a99859..3e2d812 100644
--- a/arch/x86/include/asm/stackprotector.h
+++ b/arch/x86/include/asm/stackprotector.h
@@ -41,6 +41,10 @@
#include
#include
+#if defined(CONFIG_CC_STACKPROTECTOR)
+extern unsigned long __stack_chk_guard;
+#endif
+
/*
* 24 byte read-only segment initializer for stack canary.  Linker
* can't handle the address bit shifting.  Address will be set in
@@ -79,6 +83,10 @@ static __always_inline void boot_init_stack_canary(void)
#else
this_cpu_write(stack_canary.canary, canary);
#endif
+
+#if defined(CONFIG_CC_STACKPROTECTOR)
+   __stack_chk_guard = current->stack_canary;
+#endif
}
static inline void setup_stack_canary_segment(int cpu)
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 4eb204c..5ad8ab2 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -29,6 +29,12 @@
#include
#include
+
+#ifdef CONFIG_CC_STACKPROTECTOR
+unsigned long __stack_chk_guard __read_mostly;
+EXPORT_SYMBOL(__stack_chk_guard);
+#endif
+
/*
* per-CPU TSS segments. Threads are completely 'soft' on Linux,
* no more per-task TSS's. The TSS size is kept cacheline-aligned
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 8f3ebfe..f027d25 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -39,6 +39,11 @@
#include
#include
#include
+
+#ifdef CONFIG_CC_STACKPROTECTOR
+#include
+#endif
+
#include
#include
#include
@@ -249,6 +254,11 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
*next = &next_p->thread;
int cpu = smp_processor_id();
struct tss_struct *tss = &per_cpu(init_tss, cpu);
+
+   #if defined(CONFIG_CC_STACKPROTECTOR)
+   __stack_chk_guard = next_p->stack_canary;
+   #endif
+
fpu_switch_t fpu;
/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
为啥内核能正常选择打开栈保护功能但却无法编译通过呢,后面想了想,可能有如下原因:
一是godlfish内核主要对移动手机设备使用的内核,手机一般使用的是arm芯片,对于x86架构官方关注的也许并不多。
二是默认此栈保护功能是关闭的,只有对运行稳定性有特殊需求的产品,如航天,太空类高稳定产品才需要考虑打开,打开后会稍微降低性能。
此patch应该是可以作为官网的patch来提交修复,福泽大众的,但本人从来没有提交过,限于水平有限,暂且记录,以备后忘。
 

Linux是一套免费使用和自由传播的类Unix操作系统



相关软件

2345加速浏览器官方版

2345加速浏览器官方版 | 56.2MB

2345加速浏览器官方版

新一代2345加速浏览器采用Chromium和IE双内核,主打极速与安全特性。基于Chromium深度定制,引入网页智能预加载技术,访问网页更快速..

QQ浏览器官方正式版

QQ浏览器官方正式版 | 49.67MB

QQ浏览器官方正式版

QQ浏览器秉承TT浏览器1-4系列方便易用的特点,但技术架构不同,交互和视觉表现也重新设计,采用Chromium内核+IE双内核,让浏览快速稳定...

百度浏览器最新版下载

百度浏览器最新版下载 | 13.3MB

百度浏览器最新版下载

q百度浏览器,是一款简洁轻快、智能懂你的浏览器。依靠百度强大的搜索平台,在满足用户浏览网页的基础上,它整合百度体系业务优势,带给用户更方便的浏览方式功能...

UC浏览器官方正式版

UC浏览器官方正式版 | 44.2MB

UC浏览器官方正式版

UC浏览器(UC Browser)是UC Mobile Limited在2004年8月开发的一款软件,分uc手机浏览器和uc浏览器电脑版。UC浏览器是全球使用量最大的第三方手机浏览器...

猎豹浏览器2022最新版下载

猎豹浏览器2022下载 | 45MB

猎豹浏览器2022最新版下载

猎豹安全浏览器对Chrome的Webkit内核进行了超过100项的技术优化,访问网页速度更快。其具有首创的智能切换引擎,动态选择内核匹配不同网页...

360安全浏览器官方版下载

360安全浏览器下载 | 21.4MB

360安全浏览器官方版下载

360安全浏览器拥有全国最大的恶意网址库,采用恶意网址拦截技术,可自动拦截挂马、欺诈、网银仿冒等恶意网址。独创沙箱技术,在隔离模式即使访问****也不会感染...