linux 内核裁剪不当 死机,Linux編譯x86架構內核出現_stack_chk_guard未定義錯誤
背景
android模擬器運行於virtualbox中,而virtualbox運行於x86架構的pc端,所以android及其Linux內核都編譯成x86架構。當virtualbox的vt未開啟的情況下android系統會出現各種問題,如arm庫游戲不能運行,桌面平凡掛死重啟。通過查看日志,都奔潰在了#00 pc 000183c6 /system/lib/libc.so (__get_thread+6)這個點。關於此點的日志分析過程請查看本人的另一篇文章的分析: Linux系統調用__get_thread獲取TLS失敗導致應用程序奔潰.
問題
在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未定義錯誤的修復patchdiff --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) && !defined(CONFIG_SMP))
+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) && !defined(CONFIG_SMP))
+ __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
+
+#if (defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP))
+ unsigned long __stack_chk_guard __read_mostly;
+/* 配置打開SMP時,會出現此__stack_chk_guard變量重復定義問題,所有只能在無SMP下生效 */
+//static DEFINE_PER_CPU(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
+
+#if (defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP))
+#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) && !defined(CONFIG_SMP))
+ __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來提交修復,福澤大眾的,但本人從來沒有提交過,限於水平有限,暫且記錄,以備后忘。
感謝
2017 …… ,卷起褲管跑,擼起袖子干!
linux 内核裁剪不当 死机,Linux編譯x86架構內核出現_stack_chk_guard未定義錯誤相关推荐
- Linux内核裁剪及编译
Linux内核裁剪及编译可加载模块 一 Linux基础知识 linux内核组要由五个子系统组成: 进程调度 内存管理 文件系统 网络接口 进程间通信 Linux源码目录 arch 目录中包含于体 ...
- linux 内核裁剪的具体过程和方法,Linux内核裁剪的具体过程和方法
Linux内核裁剪的具体过程和方法 这是我前段时间自己整的一份,内核功能: 能够完成系统的基本功能,上网,收发邮件等,支持xwindows图形界面. 在menuconfig中配置: 详细介绍内核配置选 ...
- 当运行 Linux 内核的机器死机时...
[CSDN 编者按]事件陷入死地无可挽救之际,可能会有人选择不了了之,有人选择就此放弃--但换个思路想一想,既然都无可挽回了,那干嘛不试试弄点有价值的信息回来? 作者 | dog250 责编 | 张 ...
- 第三十九天:linux内核裁剪
培训的第四阶段:通过编写驱动,从应用层,内核层,再到底层硬件之间的关系.明白内核驱动的意义.现在开始才是重头戏,前面的都是铺垫. 正式编写驱动前,要先了解linux内核代码的组成.linux主要是由五 ...
- [转载]基于ARM的linux内核裁剪与移植
基于ARM的linux内核裁剪与移植 http://bbs.elecfans.com/forum.php?mod=viewthread&tid=185020 wutaimin( 楼主 ) 2 ...
- ARM在嵌入式linux内核裁剪与移植的应用
微处理器用一片或少数几片大规模集成电路组成的中央处理器.这些电路执行控制部件和算术逻辑部件的功能.微处理器与传统的中央处理器相比,具有体积小,重量轻和容易模块化等优点.微处理器的基本组成部分有:寄存器 ...
- linux 脚本裁剪内核,Linux 内核裁剪的自动化方法
Linux 内核裁剪的自动化方法 随着广泛地获得使用并被移植到不同的平台,Linux 内核源代码正在越来越大,比如, Linux 2.6.28 中, 文件数有 25282 个,大小有350M. 对于某 ...
- Linux内核态之间进程通信,Linux 系统内核空间与用户空间通信的实现与分析[转载]...
[https://www.ibm.com/developerworks/cn/linux/l-netlink/index.html] 多数的 Linux 内核态程序都需要和用户空间的进程交换数据,但 ...
- 移植linux内核-映像文件,移植Linux内核-映像文件
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明 http://tigerwang202.blogbus.com/logs/43927976.html 首先从Blackfin uCli ...
最新文章
- android sqlite用户注册代码,用户名和密码登录android登录sqlite
- 微软对学生免费提供Visual Studio等开发软件(包括中国)
- 解决Eclipse 启动后总是Building WorkSpace(sleeping)
- lazadashopee代运营服务有哪些,能帮商家解决哪些问题?
- 小程序开发学习(5)---实现天气预报小程序
- android 弹出框带标题栏,Android开发靠标题栏的弹框
- A/B HDU - 1576 (逆元或拓展欧几里得或数学公式)多解法求大数结果
- C# 线程手册 第三章 使用线程 Monitor.TryEnter()
- Git 提交报错,账户和密码错误 和 git add/git commit 文件太大太多
- python常问问题_Python新手在作用域方面经常容易碰到的问题
- Python数学建模入门【1】
- Eclipse语言包及ADT安装教程
- iOS 玩转微信——下拉小程序
- 【Records】部分功能模块介绍
- 命令与征服4 You might have build the wrong LOD level 错误
- photoshop cs6基础学习
- java方法的通用格式,【学习笔记】使用Java读取、写入Excel全版本(包含xls、xslx格式)通用方法及代码展示(POI)...
- matlab画箱型图均值方差,Matlab 绘制箱线图
- php 设置数字键盘,window_win10启动时如何设置默认打开小键盘数字输入切换键?,win10作为微软的一次重大变革 - phpStudy...
- 7-38 实验7_3_奇数偶数 (100 分)