Analysis of Linux kernel stack protection __linux

Source: Internet
Author: User

One way to enable

Open the configuration config_cc_stackprotector and recompile the kernel.


Two working principle

The impact of the search configuration Config_cc_stackprotector can result in the following:

1.include/linux/stackprotector.h

#ifdef Config_cc_stackprotector
# include <asm/stackprotector.h>
#else
static inline void boot_init_stack_canary (void)
{
}
#endif

Where Asm/stackprotector.h file contents:

extern unsigned long __stack_chk_guard;


/*
* Initialize the Stackprotector canary value.
*
* Note:this must only is called from functions that never return,
* And it must always be inlined.
*/
static __always_inline void boot_init_stack_canary (void)
{
unsigned long canary;


/* Try to get a semi random initial value. */
Get_random_bytes (&canary, sizeof (Canary));
Canary ^= Linux_version_code;


Current->stack_canary = Canary;
__stack_chk_guard = current->stack_canary;
}


2.kernel/fork.c

#ifdef Config_cc_stackprotector
Tsk->stack_canary = Pax_get_random_long ();
#endif


3.kernel/panic.c

#ifdef Config_cc_stackprotector

/*
* Called when GCC ' s-fstack-protector feature is used, and
* GCC detects corruption of the On-stack Canary value
*/
void __stack_chk_fail (void)
{
Dump_stack ();
Panic ("Stack-protector:kernel stack is corrupted in:%pa\n",
__builtin_return_address (0));
}
Export_symbol (__stack_chk_fail);
#endif


4.arch/mips/kernel/process.c

#ifdef Config_cc_stackprotector
#include <linux/stackprotector.h>
unsigned long __stack_chk_guard __read_mostly;
Export_symbol (__stack_chk_guard);
#endif


5.include/linux/sched.h

struct Task_struct {

......

#ifdef Config_cc_stackprotector
/* Canary value for the-fstack-protector gcc feature * *
unsigned long stack_canary;
#endif

....

}

6.arch/mips/kernel/r4k_switch.s

LEAF (Resume)

....

#if defined (config_cc_stackprotector) &&!defined (CONFIG_SMP)
Ptr_la T8, __stack_chk_guard
Long_l T9, task_stack_canary (A1)
Long_s T9, 0 (T8)
#endif


7.arch/mips/makefile

Ifdef config_cc_stackprotector
Kbuild_cflags + +-fstack-protector
endif

These search results can be summed up as: Define and set the variable __stack_chk_guard, define the function __stack_chk_fail (), but found __stack_chk_guard settings are not used, the function __stack_chk_ Fail () has not been called, and suddenly the clue is broken.

But since they are defined, they will be used, and the kernel will not rely on other library files, so they intend to start from the obj file, casually found a init/mounts.o, look at the following relocation table, as follows:

Relocation RECORDS for [. Init.text]:
OFFSET TYPE VALUE

.......

00000120 r_mips_hi16 __stack_chk_guard
00000124 r_mips_lo16 __stack_chk_guard

........

00000344 r_mips_hi16 __stack_chk_guard
0000034c r_mips_lo16 __stack_chk_guard
00000358 r_mips_26 __stack_chk_fail
00000388 r_mips_hi16 __stack_chk_guard
00000390 r_mips_lo16 __stack_chk_guard

From the relocation table, __stack_chk_fail and __stack_chk_guard are actually used to view the corresponding disassembly results:

Disassembly of section. Init.text

.........

00000120 <mount_block_root>:
120:3c020000 lui v0,0x0
124:8c420000 LW v0,0 (v0)
128:27bdff98 Addiu sp,sp,-104
12c:afa2003c SW v0,60 (SP)
130:3c020000 lui v0,0x0
134:afb70060 SW s7,96 (SP)
138:0080b821 Move s7,a0
13c:8c440000 LW a0,0 (v0)
140:afb2004c SW s2,76 (SP)

..........

33c:0c000000 JAL 0 <readonly>
340:02002821 Move A1,s0
344:3c020000 lui v0,0x0
348:8fa3003c LW v1,60 (SP)
34c:8c420000 LW v0,0 (v0)
350:10620003 beq v1,v0,360 <mount_block_root+0x240>
354:8fbf0064 LW ra,100 (SP)
358:0c000000 JAL 0 <readonly>
35c:00000000 NOP
360:8fb70060 LW s7,96 (SP)
364:8fb6005c LW s6,92 (SP)
368:8fb50058 LW s5,88 (SP)
36c:8fb40054 LW s4,84 (SP)

Open init/mounts.c file, find Mount_block_root () function, found and did not call __stack_chk_fail and __stack_chk_guard, immediately understand, this should follow the search results above 7, Compile options-fstack-protector related, by contrasting the assembly code, at the function entrance:

120:3c020000 lui v0,0x0
124:8c420000 LW v0,0 (v0)
128:27bdff98 Addiu sp,sp,-104
12c:afa2003c SW v0,60 (SP)

Save the __stack_chk_guard value to the top of the stack, and then before the function returns:

344:3c020000 lui v0,0x0
348:8fa3003c LW v1,60 (SP)
34c:8c420000 LW v0,0 (v0)
350:10620003 beq v1,v0,360 <mount_block_root+0x240>

Remove the value saved at the top of the current stack and compare it to the __stack_chk_guard, and if it is equal, jump to 360 and return smoothly, otherwise proceed sequentially:

354:8fbf0064 LW ra,100 (SP)
358:0c000000 JAL 0 <readonly>

By looking at the relocation table above, 00000358 r_mips_26 __stack_chk_fail, the call is __stack_chk_fail () This function, so the whole process should be very clear, compile options-fstack-protect or inserts some code at the function compile time, the function entry stores the __stack_chk_guard value on the top of the stack, takes out the value stored on the top of the stack and compares the __stack_chk_guard before the function returns, if the memory overflow modifies the stored value, the result of the comparison is not equal. Call __stack_chk_fail, the kernel __stack_chk_fail () function goes down directly.


Three supplementary notes

Through the above inference, it is found that the key is to __stack_chk_guard the value of the security, this value is when the kernel started, call the Boot_init_stack_canary () function randomly generated, so theoretically this value is not guessed. In addition, each process corresponds to a different value: Tsk->stack_canary = Pax_get_random_long (); This further increases security by setting the stack_canary of the process that will run each time the process switches to __stack_ Chk_guard, but for multi-core processors, because __stack_chk_guard only saves one copy, not per CPU variable, the __stack_chk_guard value does not change when the process is switched, because if a CPU core occurs with a process switch, Reset changes the value of __stack_chk_guard, the other CPU cores that are running in the kernel may be checked when the function returns but two cause system downtime. As for __stack_chk_guard why not make the per CPU variable, this is well understood, because GCC will only reference __stack_chk_guard this variable.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.