diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-02-26 06:55:57 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-02-26 06:55:57 -0500 |
commit | 5d119b2c9a490e2d647eae134211b32a18a04c7d (patch) | |
tree | 37f40ec2e3ae4ad793d6c4c40f253e4266895d09 /arch/x86/kernel/process_64.c | |
parent | ce28b9864b853803320c3f1d8de1b81aa4120b14 (diff) |
x86: fix execve with -fstack-protect
pointed out by pageexec@freemail.hu:
> what happens here is that gcc treats the argument area as owned by the
> callee, not the caller and is allowed to do certain tricks. for ssp it
> will make a copy of the struct passed by value into the local variable
> area and pass *its* address down, and it won't copy it back into the
> original instance stored in the argument area.
>
> so once sys_execve returns, the pt_regs passed by value hasn't at all
> changed and its default content will cause a nice double fault (FWIW,
> this part took me the longest to debug, being down with cold didn't
> help it either ;).
To fix this we pass in pt_regs by pointer.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/process_64.c')
-rw-r--r-- | arch/x86/kernel/process_64.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index b0cc8f0136d8..43f287744f9f 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -730,16 +730,16 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
730 | */ | 730 | */ |
731 | asmlinkage | 731 | asmlinkage |
732 | long sys_execve(char __user *name, char __user * __user *argv, | 732 | long sys_execve(char __user *name, char __user * __user *argv, |
733 | char __user * __user *envp, struct pt_regs regs) | 733 | char __user * __user *envp, struct pt_regs *regs) |
734 | { | 734 | { |
735 | long error; | 735 | long error; |
736 | char * filename; | 736 | char * filename; |
737 | 737 | ||
738 | filename = getname(name); | 738 | filename = getname(name); |
739 | error = PTR_ERR(filename); | 739 | error = PTR_ERR(filename); |
740 | if (IS_ERR(filename)) | 740 | if (IS_ERR(filename)) |
741 | return error; | 741 | return error; |
742 | error = do_execve(filename, argv, envp, ®s); | 742 | error = do_execve(filename, argv, envp, regs); |
743 | putname(filename); | 743 | putname(filename); |
744 | return error; | 744 | return error; |
745 | } | 745 | } |