Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753388AbbDGJle (ORCPT ); Tue, 7 Apr 2015 05:41:34 -0400 Received: from terminus.zytor.com ([198.137.202.10]:48231 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752914AbbDGJlW (ORCPT ); Tue, 7 Apr 2015 05:41:22 -0400 Date: Tue, 7 Apr 2015 02:40:47 -0700 From: tip-bot for Denys Vlasenko Message-ID: Cc: hpa@zytor.com, luto@amacapital.net, torvalds@linux-foundation.org, rostedt@goodmis.org, mingo@kernel.org, ast@plumgrid.com, tglx@linutronix.de, linux-kernel@vger.kernel.org, bp@alien8.de, dvlasenk@redhat.com, fweisbec@gmail.com, keescook@chromium.org, oleg@redhat.com, wad@chromium.org Reply-To: bp@alien8.de, linux-kernel@vger.kernel.org, tglx@linutronix.de, ast@plumgrid.com, mingo@kernel.org, rostedt@goodmis.org, torvalds@linux-foundation.org, luto@amacapital.net, hpa@zytor.com, wad@chromium.org, oleg@redhat.com, keescook@chromium.org, fweisbec@gmail.com, dvlasenk@redhat.com In-Reply-To: <1428173719-7637-1-git-send-email-dvlasenk@redhat.com> References: <1428173719-7637-1-git-send-email-dvlasenk@redhat.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:x86/asm] x86/asm/entry: Clear EXTRA_REGS for all executable formats Git-Commit-ID: fc3e958a2b552fe6210e6de3bebb4348156a0b5f X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5229 Lines: 175 Commit-ID: fc3e958a2b552fe6210e6de3bebb4348156a0b5f Gitweb: http://git.kernel.org/tip/fc3e958a2b552fe6210e6de3bebb4348156a0b5f Author: Denys Vlasenko AuthorDate: Sat, 4 Apr 2015 20:55:19 +0200 Committer: Ingo Molnar CommitDate: Mon, 6 Apr 2015 09:24:08 +0200 x86/asm/entry: Clear EXTRA_REGS for all executable formats On failure, sys_execve() does not clobber EXTRA_REGS, so we can just return to userpsace without saving/restoring them. On success, ELF_PLAT_INIT() in sys_execve() clears all these registers. On other executable formats: - binfmt_flat.c has similar FLAT_PLAT_INIT, but x86 (and everyone else except sh) doesn't define it. - binfmt_elf_fdpic.c has ELF_FDPIC_PLAT_INIT, but x86 (and most others) doesn't define it. - There are no such hooks in binfmt_aout.c et al. We inherit EXTRA_REGS from the prior executable. This inconsistency was not intended. This change removes SAVE/RESTORE_EXTRA_REGS in stub_execve, removes register clearing in ELF_PLAT_INIT(), and instead simply clears them on success in stub_execve. Run-tested. Signed-off-by: Denys Vlasenko Cc: Alexei Starovoitov Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Steven Rostedt Cc: Will Drewry Link: http://lkml.kernel.org/r/1428173719-7637-1-git-send-email-dvlasenk@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/calling.h | 9 ++++++++ arch/x86/include/asm/elf.h | 7 +++--- arch/x86/kernel/entry_64.S | 50 +++++++++++++++++++----------------------- 3 files changed, 35 insertions(+), 31 deletions(-) diff --git a/arch/x86/include/asm/calling.h b/arch/x86/include/asm/calling.h index 4b5f7bf..1c8b50e 100644 --- a/arch/x86/include/asm/calling.h +++ b/arch/x86/include/asm/calling.h @@ -151,6 +151,15 @@ For 32-bit we have the following conventions - kernel is built with movq_cfi_restore 5*8+\offset, rbx .endm + .macro ZERO_EXTRA_REGS + xorl %r15d, %r15d + xorl %r14d, %r14d + xorl %r13d, %r13d + xorl %r12d, %r12d + xorl %ebp, %ebp + xorl %ebx, %ebx + .endm + .macro RESTORE_C_REGS_HELPER rstor_rax=1, rstor_rcx=1, rstor_r11=1, rstor_r8910=1, rstor_rdx=1 .if \rstor_r11 movq_cfi_restore 6*8, r11 diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h index ca3347a..3563107 100644 --- a/arch/x86/include/asm/elf.h +++ b/arch/x86/include/asm/elf.h @@ -171,10 +171,11 @@ do { \ static inline void elf_common_init(struct thread_struct *t, struct pt_regs *regs, const u16 ds) { - regs->ax = regs->bx = regs->cx = regs->dx = 0; - regs->si = regs->di = regs->bp = 0; + /* Commented-out registers are cleared in stub_execve */ + /*regs->ax = regs->bx =*/ regs->cx = regs->dx = 0; + regs->si = regs->di /*= regs->bp*/ = 0; regs->r8 = regs->r9 = regs->r10 = regs->r11 = 0; - regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0; + /*regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0;*/ t->fs = t->gs = 0; t->fsindex = t->gsindex = 0; t->ds = t->es = ds; diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 386375d..f4270ff 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -419,25 +419,27 @@ END(stub_\func) ENTRY(stub_execve) CFI_STARTPROC - addq $8, %rsp - DEFAULT_FRAME 0 - SAVE_EXTRA_REGS - call sys_execve - movq %rax,RAX(%rsp) - RESTORE_EXTRA_REGS - jmp int_ret_from_sys_call + DEFAULT_FRAME 0, 8 + call sys_execve +return_from_execve: + testl %eax, %eax + jz 1f + /* exec failed, can use fast SYSRET code path in this case */ + ret +1: + /* must use IRET code path (pt_regs->cs may have changed) */ + addq $8, %rsp + ZERO_EXTRA_REGS + movq %rax,RAX(%rsp) + jmp int_ret_from_sys_call CFI_ENDPROC END(stub_execve) ENTRY(stub_execveat) CFI_STARTPROC - addq $8, %rsp - DEFAULT_FRAME 0 - SAVE_EXTRA_REGS - call sys_execveat - movq %rax,RAX(%rsp) - RESTORE_EXTRA_REGS - jmp int_ret_from_sys_call + DEFAULT_FRAME 0, 8 + call sys_execveat + jmp return_from_execve CFI_ENDPROC END(stub_execveat) @@ -472,25 +474,17 @@ END(stub_x32_rt_sigreturn) ENTRY(stub_x32_execve) CFI_STARTPROC - addq $8, %rsp - DEFAULT_FRAME 0 - SAVE_EXTRA_REGS - call compat_sys_execve - movq %rax,RAX(%rsp) - RESTORE_EXTRA_REGS - jmp int_ret_from_sys_call + DEFAULT_FRAME 0, 8 + call compat_sys_execve + jmp return_from_execve CFI_ENDPROC END(stub_x32_execve) ENTRY(stub_x32_execveat) CFI_STARTPROC - addq $8, %rsp - DEFAULT_FRAME 0 - SAVE_EXTRA_REGS - call compat_sys_execveat - movq %rax,RAX(%rsp) - RESTORE_EXTRA_REGS - jmp int_ret_from_sys_call + DEFAULT_FRAME 0, 8 + call compat_sys_execveat + jmp return_from_execve CFI_ENDPROC END(stub_x32_execveat) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/