Linux Compiler x86 Architecture Kernel Occurs _stack_chk_guard Definition Error

Keywords: Android Linux git VirtualBox


android simulator runs in virtualbox, while VirtualBox runs on the pc side of X86 architecture, so both android and its Linux kernel are compiled into x86 architecture. When virtual box's vt is not turned on, android system will have various problems, such as arm library game can not run, desktop ordinary hang dead restart. By looking at the logs, they all crashed at 00 pc 000183c6 / system / lib / libc. so (get_thread + 6). For the log analysis process on this point, please see my analysis of another article: Failure of Linux system call u get_thread to get TLS results in application crash.


When the android kernel is 3.10, choose CONFIG_CC_STACKPROTECTOR=y (turn on the protection function of the kernel stack). Under the x86 architecture, it can compile and solve the problems of desktop hanging repeatedly under vt and arm library games can not be played. But if the android kernel is upgraded to 3.18 and the stack protection function is turned on by the kernel, compilation errors will occur when the linux kernel under the X86 framework is cross-compiled. Look specifically at turning on the kernel configuration and error log as follows:

Kernel configuration options for opening 3.18 stack protection are as follows:

 CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-ecx -fcall-saved-edx"
@@ -249,10 +248,10 @@ CONFIG_HAVE_CMPXCHG_DOUBLE=y

After opening the 3.18 kernel stack protection configuration, the kernel compiles x86 schema errors as follows:

  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

Analysis and solution

The above error: undefined reference to'u stack_chk_guard'error has not found a positive solution through various google, some say that gcc needs 4.9 or more, but cross-compiling tool 4.9 is not good. Also checked the android source code on stack protector related fixes, there is no use for eggs. Finally, by looking at the u stack_chk_guard field, it is found that the x86 architecture does not define this field, while sh,arm,mips and other architectures are defined. At the end of the road, you can only draw your own gourds and look forward to progress. The following patch is added for myself, not only to solve compilation errors, but also to solve the problems of running android images under virtual box when vt is not open.

When Linux compiles x86 architecture u stack_chk_guard does not define a patch to fix errors

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 <asm/desc.h>
 #include <linux/random.h>

+#if (defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP))
+extern unsigned long __stack_chk_guard;
  * 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)
    this_cpu_write(stack_canary.canary, canary);
+#if (defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP))
+   __stack_chk_guard = current->stack_canary;

 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 <asm/debugreg.h>
 #include <asm/nmi.h>

+#if (defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP))
+ unsigned long __stack_chk_guard __read_mostly; 
+/* When configuring to open SMP, this problem of redefining the u stack_chk_guard variable will arise, all of which can only take effect in the absence of SMP. */
+//static DEFINE_PER_CPU(unsigned long,__stack_chk_guard) __read_mostly;
  * 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 <asm/pgtable.h>
 #include <asm/ldt.h>
 #include <asm/processor.h>
+#if (defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP))
+#include <linux/stackprotector.h>
 #include <asm/i387.h>
 #include <asm/fpu-internal.h>
 #include <asm/desc.h>
@@ -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 */

Why can the kernel choose to open the stack protection function normally, but can not compile through it? After thinking about it later, there may be the following reasons:

  • First, the godlfish kernel is mainly used for mobile phone devices. Mobile phones generally use arm chips. Official attention to x86 architecture may not be much.
  • The other is that the protection function of this stack is closed by default. Only products with special requirements for operational stability, such as aerospace and space products with high stability, need to be considered to open, which will slightly reduce the performance after opening.
  • This patch should be used as the patch of the official website to submit repairs, Fukuzawa Volkswagen, but I have never submitted it, limited to the level, temporary records, in order to memorize.

[Note: For the principle of kernel stack protection, you can refer to the article: Analysis of CC_STACKPROTECTOR Anti-Kernel Stack Overflow Patches]


2017... Roll up your trousers and run, roll up your sleeves and dry them!

Column by yanxiangyfg :  "Be faithful to practice and record every bit"

Posted by bluebutterflyofyourmind on Sat, 29 Dec 2018 10:09:08 -0800