diff options
-rw-r--r-- | arch/x86_64/kernel/process.c | 8 | ||||
-rw-r--r-- | include/asm-x86_64/pda.h | 7 | ||||
-rw-r--r-- | include/linux/sched.h | 5 | ||||
-rw-r--r-- | kernel/fork.c | 5 |
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); |