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/entry_64.S | |
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/entry_64.S')
-rw-r--r-- | arch/x86/kernel/entry_64.S | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 2ad9a1bc6a73..c20c9e7e08dd 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -453,6 +453,7 @@ ENTRY(stub_execve) | |||
453 | CFI_REGISTER rip, r11 | 453 | CFI_REGISTER rip, r11 |
454 | SAVE_REST | 454 | SAVE_REST |
455 | FIXUP_TOP_OF_STACK %r11 | 455 | FIXUP_TOP_OF_STACK %r11 |
456 | movq %rsp, %rcx | ||
456 | call sys_execve | 457 | call sys_execve |
457 | RESTORE_TOP_OF_STACK %r11 | 458 | RESTORE_TOP_OF_STACK %r11 |
458 | movq %rax,RAX(%rsp) | 459 | movq %rax,RAX(%rsp) |
@@ -1036,15 +1037,16 @@ ENDPROC(child_rip) | |||
1036 | * rdi: name, rsi: argv, rdx: envp | 1037 | * rdi: name, rsi: argv, rdx: envp |
1037 | * | 1038 | * |
1038 | * We want to fallback into: | 1039 | * We want to fallback into: |
1039 | * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs) | 1040 | * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs *regs) |
1040 | * | 1041 | * |
1041 | * do_sys_execve asm fallback arguments: | 1042 | * do_sys_execve asm fallback arguments: |
1042 | * rdi: name, rsi: argv, rdx: envp, fake frame on the stack | 1043 | * rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack |
1043 | */ | 1044 | */ |
1044 | ENTRY(kernel_execve) | 1045 | ENTRY(kernel_execve) |
1045 | CFI_STARTPROC | 1046 | CFI_STARTPROC |
1046 | FAKE_STACK_FRAME $0 | 1047 | FAKE_STACK_FRAME $0 |
1047 | SAVE_ALL | 1048 | SAVE_ALL |
1049 | movq %rsp,%rcx | ||
1048 | call sys_execve | 1050 | call sys_execve |
1049 | movq %rax, RAX(%rsp) | 1051 | movq %rax, RAX(%rsp) |
1050 | RESTORE_REST | 1052 | RESTORE_REST |