aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/kernel/process.c8
-rw-r--r--include/asm-x86_64/pda.h7
-rw-r--r--include/linux/sched.h5
-rw-r--r--kernel/fork.c5
4 files changed, 24 insertions, 1 deletions
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 9e9a70e50c72..fba8dfeda67c 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -625,6 +625,14 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
625 unlazy_fpu(prev_p); 625 unlazy_fpu(prev_p);
626 write_pda(kernelstack, 626 write_pda(kernelstack,
627 task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); 627 task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
628#ifdef CONFIG_CC_STACKPROTECTOR
629 write_pda(stack_canary, next_p->stack_canary);
630 /*
631 * Build time only check to make sure the stack_canary is at
632 * offset 40 in the pda; this is a gcc ABI requirement
633 */
634 BUILD_BUG_ON(offsetof(struct x8664_pda, stack_canary) != 40);
635#endif
628 636
629 /* 637 /*
630 * Now maybe reload the debug registers and handle I/O bitmaps 638 * Now maybe reload the debug registers and handle I/O bitmaps
diff --git a/include/asm-x86_64/pda.h b/include/asm-x86_64/pda.h
index 6794ffaae433..e7773e0af865 100644
--- a/include/asm-x86_64/pda.h
+++ b/include/asm-x86_64/pda.h
@@ -16,7 +16,12 @@ struct x8664_pda {
16 unsigned long oldrsp; /* 24 user rsp for system call */ 16 unsigned long oldrsp; /* 24 user rsp for system call */
17 int irqcount; /* 32 Irq nesting counter. Starts with -1 */ 17 int irqcount; /* 32 Irq nesting counter. Starts with -1 */
18 int cpunumber; /* 36 Logical CPU number */ 18 int cpunumber; /* 36 Logical CPU number */
19 char *irqstackptr; /* 40 top of irqstack */ 19#ifdef CONFIG_CC_STACKPROTECTOR
20 unsigned long stack_canary; /* 40 stack canary value */
21 /* gcc-ABI: this canary MUST be at
22 offset 40!!! */
23#endif
24 char *irqstackptr;
20 int nodenumber; /* number of current node */ 25 int nodenumber; /* number of current node */
21 unsigned int __softirq_pending; 26 unsigned int __softirq_pending;
22 unsigned int __nmi_count; /* number of NMI on this CPUs */ 27 unsigned int __nmi_count; /* number of NMI on this CPUs */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 807556c5bcd2..9d4aa7f95bc8 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -819,6 +819,11 @@ struct task_struct {
819 unsigned did_exec:1; 819 unsigned did_exec:1;
820 pid_t pid; 820 pid_t pid;
821 pid_t tgid; 821 pid_t tgid;
822
823#ifdef CONFIG_CC_STACKPROTECTOR
824 /* Canary value for the -fstack-protector gcc feature */
825 unsigned long stack_canary;
826#endif
822 /* 827 /*
823 * pointers to (original) parent process, youngest child, younger sibling, 828 * pointers to (original) parent process, youngest child, younger sibling,
824 * older sibling, respectively. (p->father can be replaced with 829 * older sibling, respectively. (p->father can be replaced with
diff --git a/kernel/fork.c b/kernel/fork.c
index f9b014e3e700..a0dad84567c9 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -45,6 +45,7 @@
45#include <linux/cn_proc.h> 45#include <linux/cn_proc.h>
46#include <linux/delayacct.h> 46#include <linux/delayacct.h>
47#include <linux/taskstats_kern.h> 47#include <linux/taskstats_kern.h>
48#include <linux/random.h>
48 49
49#include <asm/pgtable.h> 50#include <asm/pgtable.h>
50#include <asm/pgalloc.h> 51#include <asm/pgalloc.h>
@@ -175,6 +176,10 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
175 tsk->thread_info = ti; 176 tsk->thread_info = ti;
176 setup_thread_stack(tsk, orig); 177 setup_thread_stack(tsk, orig);
177 178
179#ifdef CONFIG_CC_STACKPROTECTOR
180 tsk->stack_canary = get_random_int();
181#endif
182
178 /* One for us, one for whoever does the "release_task()" (usually parent) */ 183 /* One for us, one for whoever does the "release_task()" (usually parent) */
179 atomic_set(&tsk->usage,2); 184 atomic_set(&tsk->usage,2);
180 atomic_set(&tsk->fs_excl, 0); 185 atomic_set(&tsk->fs_excl, 0);