.. | .. |
---|
6 | 6 | * the stack frame and verifying that it hasn't been overwritten when |
---|
7 | 7 | * returning from the function. The pattern is called stack canary |
---|
8 | 8 | * and gcc expects it to be defined by a global variable called |
---|
9 | | - * "__stack_chk_guard" on ARM. This unfortunately means that on SMP |
---|
10 | | - * we cannot have a different canary value per task. |
---|
| 9 | + * "__stack_chk_guard" on ARM. This prevents SMP systems from using a |
---|
| 10 | + * different value for each task unless we enable a GCC plugin that |
---|
| 11 | + * replaces these symbol references with references to each task's own |
---|
| 12 | + * value. |
---|
11 | 13 | */ |
---|
12 | 14 | |
---|
13 | 15 | #ifndef _ASM_STACKPROTECTOR_H |
---|
.. | .. |
---|
15 | 17 | |
---|
16 | 18 | #include <linux/random.h> |
---|
17 | 19 | #include <linux/version.h> |
---|
| 20 | + |
---|
| 21 | +#include <asm/thread_info.h> |
---|
18 | 22 | |
---|
19 | 23 | extern unsigned long __stack_chk_guard; |
---|
20 | 24 | |
---|
.. | .. |
---|
33 | 37 | canary ^= LINUX_VERSION_CODE; |
---|
34 | 38 | |
---|
35 | 39 | current->stack_canary = canary; |
---|
| 40 | +#ifndef CONFIG_STACKPROTECTOR_PER_TASK |
---|
36 | 41 | __stack_chk_guard = current->stack_canary; |
---|
| 42 | +#else |
---|
| 43 | + current_thread_info()->stack_canary = current->stack_canary; |
---|
| 44 | +#endif |
---|
37 | 45 | } |
---|
38 | 46 | |
---|
39 | 47 | #endif /* _ASM_STACKPROTECTOR_H */ |
---|