Commit 5d119b2c authored by Ingo Molnar's avatar Ingo Molnar

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: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent ce28b986
...@@ -453,6 +453,7 @@ ENTRY(stub_execve) ...@@ -453,6 +453,7 @@ ENTRY(stub_execve)
CFI_REGISTER rip, r11 CFI_REGISTER rip, r11
SAVE_REST SAVE_REST
FIXUP_TOP_OF_STACK %r11 FIXUP_TOP_OF_STACK %r11
movq %rsp, %rcx
call sys_execve call sys_execve
RESTORE_TOP_OF_STACK %r11 RESTORE_TOP_OF_STACK %r11
movq %rax,RAX(%rsp) movq %rax,RAX(%rsp)
...@@ -1036,15 +1037,16 @@ ENDPROC(child_rip) ...@@ -1036,15 +1037,16 @@ ENDPROC(child_rip)
* rdi: name, rsi: argv, rdx: envp * rdi: name, rsi: argv, rdx: envp
* *
* We want to fallback into: * We want to fallback into:
* extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs) * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs *regs)
* *
* do_sys_execve asm fallback arguments: * do_sys_execve asm fallback arguments:
* rdi: name, rsi: argv, rdx: envp, fake frame on the stack * rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack
*/ */
ENTRY(kernel_execve) ENTRY(kernel_execve)
CFI_STARTPROC CFI_STARTPROC
FAKE_STACK_FRAME $0 FAKE_STACK_FRAME $0
SAVE_ALL SAVE_ALL
movq %rsp,%rcx
call sys_execve call sys_execve
movq %rax, RAX(%rsp) movq %rax, RAX(%rsp)
RESTORE_REST RESTORE_REST
......
...@@ -730,16 +730,16 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) ...@@ -730,16 +730,16 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
*/ */
asmlinkage asmlinkage
long sys_execve(char __user *name, char __user * __user *argv, long sys_execve(char __user *name, char __user * __user *argv,
char __user * __user *envp, struct pt_regs regs) char __user * __user *envp, struct pt_regs *regs)
{ {
long error; long error;
char * filename; char * filename;
filename = getname(name); filename = getname(name);
error = PTR_ERR(filename); error = PTR_ERR(filename);
if (IS_ERR(filename)) if (IS_ERR(filename))
return error; return error;
error = do_execve(filename, argv, envp, &regs); error = do_execve(filename, argv, envp, regs);
putname(filename); putname(filename);
return error; return error;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment