x86-32, smap: Add STAC/CLAC instructions to 32-bit kernel entry

The changes to entry_32.S got missed in checkin:

63bcff2a x86, smap: Add STAC and CLAC instructions to control user space access

The resulting kernel was largely functional but SMAP protection could
have been bypassed.

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Link: http://lkml.kernel.org/r/1348256595-29119-9-git-send-email-hpa@linux.intel.com
This commit is contained in:
H. Peter Anvin 2012-09-21 13:58:10 -07:00
parent 5e88353d8b
commit e59d1b0a24

View File

@ -57,6 +57,7 @@
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#include <asm/alternative-asm.h> #include <asm/alternative-asm.h>
#include <asm/asm.h> #include <asm/asm.h>
#include <asm/smap.h>
/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */ /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
#include <linux/elf-em.h> #include <linux/elf-em.h>
@ -407,7 +408,9 @@ sysenter_past_esp:
*/ */
cmpl $__PAGE_OFFSET-3,%ebp cmpl $__PAGE_OFFSET-3,%ebp
jae syscall_fault jae syscall_fault
ASM_STAC
1: movl (%ebp),%ebp 1: movl (%ebp),%ebp
ASM_CLAC
movl %ebp,PT_EBP(%esp) movl %ebp,PT_EBP(%esp)
_ASM_EXTABLE(1b,syscall_fault) _ASM_EXTABLE(1b,syscall_fault)
@ -488,6 +491,7 @@ ENDPROC(ia32_sysenter_target)
# system call handler stub # system call handler stub
ENTRY(system_call) ENTRY(system_call)
RING0_INT_FRAME # can't unwind into user space anyway RING0_INT_FRAME # can't unwind into user space anyway
ASM_CLAC
pushl_cfi %eax # save orig_eax pushl_cfi %eax # save orig_eax
SAVE_ALL SAVE_ALL
GET_THREAD_INFO(%ebp) GET_THREAD_INFO(%ebp)
@ -670,6 +674,7 @@ END(syscall_exit_work)
RING0_INT_FRAME # can't unwind into user space anyway RING0_INT_FRAME # can't unwind into user space anyway
syscall_fault: syscall_fault:
ASM_CLAC
GET_THREAD_INFO(%ebp) GET_THREAD_INFO(%ebp)
movl $-EFAULT,PT_EAX(%esp) movl $-EFAULT,PT_EAX(%esp)
jmp resume_userspace jmp resume_userspace
@ -825,6 +830,7 @@ END(interrupt)
*/ */
.p2align CONFIG_X86_L1_CACHE_SHIFT .p2align CONFIG_X86_L1_CACHE_SHIFT
common_interrupt: common_interrupt:
ASM_CLAC
addl $-0x80,(%esp) /* Adjust vector into the [-256,-1] range */ addl $-0x80,(%esp) /* Adjust vector into the [-256,-1] range */
SAVE_ALL SAVE_ALL
TRACE_IRQS_OFF TRACE_IRQS_OFF
@ -841,6 +847,7 @@ ENDPROC(common_interrupt)
#define BUILD_INTERRUPT3(name, nr, fn) \ #define BUILD_INTERRUPT3(name, nr, fn) \
ENTRY(name) \ ENTRY(name) \
RING0_INT_FRAME; \ RING0_INT_FRAME; \
ASM_CLAC; \
pushl_cfi $~(nr); \ pushl_cfi $~(nr); \
SAVE_ALL; \ SAVE_ALL; \
TRACE_IRQS_OFF \ TRACE_IRQS_OFF \
@ -857,6 +864,7 @@ ENDPROC(name)
ENTRY(coprocessor_error) ENTRY(coprocessor_error)
RING0_INT_FRAME RING0_INT_FRAME
ASM_CLAC
pushl_cfi $0 pushl_cfi $0
pushl_cfi $do_coprocessor_error pushl_cfi $do_coprocessor_error
jmp error_code jmp error_code
@ -865,6 +873,7 @@ END(coprocessor_error)
ENTRY(simd_coprocessor_error) ENTRY(simd_coprocessor_error)
RING0_INT_FRAME RING0_INT_FRAME
ASM_CLAC
pushl_cfi $0 pushl_cfi $0
#ifdef CONFIG_X86_INVD_BUG #ifdef CONFIG_X86_INVD_BUG
/* AMD 486 bug: invd from userspace calls exception 19 instead of #GP */ /* AMD 486 bug: invd from userspace calls exception 19 instead of #GP */
@ -886,6 +895,7 @@ END(simd_coprocessor_error)
ENTRY(device_not_available) ENTRY(device_not_available)
RING0_INT_FRAME RING0_INT_FRAME
ASM_CLAC
pushl_cfi $-1 # mark this as an int pushl_cfi $-1 # mark this as an int
pushl_cfi $do_device_not_available pushl_cfi $do_device_not_available
jmp error_code jmp error_code
@ -906,6 +916,7 @@ END(native_irq_enable_sysexit)
ENTRY(overflow) ENTRY(overflow)
RING0_INT_FRAME RING0_INT_FRAME
ASM_CLAC
pushl_cfi $0 pushl_cfi $0
pushl_cfi $do_overflow pushl_cfi $do_overflow
jmp error_code jmp error_code
@ -914,6 +925,7 @@ END(overflow)
ENTRY(bounds) ENTRY(bounds)
RING0_INT_FRAME RING0_INT_FRAME
ASM_CLAC
pushl_cfi $0 pushl_cfi $0
pushl_cfi $do_bounds pushl_cfi $do_bounds
jmp error_code jmp error_code
@ -922,6 +934,7 @@ END(bounds)
ENTRY(invalid_op) ENTRY(invalid_op)
RING0_INT_FRAME RING0_INT_FRAME
ASM_CLAC
pushl_cfi $0 pushl_cfi $0
pushl_cfi $do_invalid_op pushl_cfi $do_invalid_op
jmp error_code jmp error_code
@ -930,6 +943,7 @@ END(invalid_op)
ENTRY(coprocessor_segment_overrun) ENTRY(coprocessor_segment_overrun)
RING0_INT_FRAME RING0_INT_FRAME
ASM_CLAC
pushl_cfi $0 pushl_cfi $0
pushl_cfi $do_coprocessor_segment_overrun pushl_cfi $do_coprocessor_segment_overrun
jmp error_code jmp error_code
@ -938,6 +952,7 @@ END(coprocessor_segment_overrun)
ENTRY(invalid_TSS) ENTRY(invalid_TSS)
RING0_EC_FRAME RING0_EC_FRAME
ASM_CLAC
pushl_cfi $do_invalid_TSS pushl_cfi $do_invalid_TSS
jmp error_code jmp error_code
CFI_ENDPROC CFI_ENDPROC
@ -945,6 +960,7 @@ END(invalid_TSS)
ENTRY(segment_not_present) ENTRY(segment_not_present)
RING0_EC_FRAME RING0_EC_FRAME
ASM_CLAC
pushl_cfi $do_segment_not_present pushl_cfi $do_segment_not_present
jmp error_code jmp error_code
CFI_ENDPROC CFI_ENDPROC
@ -952,6 +968,7 @@ END(segment_not_present)
ENTRY(stack_segment) ENTRY(stack_segment)
RING0_EC_FRAME RING0_EC_FRAME
ASM_CLAC
pushl_cfi $do_stack_segment pushl_cfi $do_stack_segment
jmp error_code jmp error_code
CFI_ENDPROC CFI_ENDPROC
@ -959,6 +976,7 @@ END(stack_segment)
ENTRY(alignment_check) ENTRY(alignment_check)
RING0_EC_FRAME RING0_EC_FRAME
ASM_CLAC
pushl_cfi $do_alignment_check pushl_cfi $do_alignment_check
jmp error_code jmp error_code
CFI_ENDPROC CFI_ENDPROC
@ -966,6 +984,7 @@ END(alignment_check)
ENTRY(divide_error) ENTRY(divide_error)
RING0_INT_FRAME RING0_INT_FRAME
ASM_CLAC
pushl_cfi $0 # no error code pushl_cfi $0 # no error code
pushl_cfi $do_divide_error pushl_cfi $do_divide_error
jmp error_code jmp error_code
@ -975,6 +994,7 @@ END(divide_error)
#ifdef CONFIG_X86_MCE #ifdef CONFIG_X86_MCE
ENTRY(machine_check) ENTRY(machine_check)
RING0_INT_FRAME RING0_INT_FRAME
ASM_CLAC
pushl_cfi $0 pushl_cfi $0
pushl_cfi machine_check_vector pushl_cfi machine_check_vector
jmp error_code jmp error_code
@ -984,6 +1004,7 @@ END(machine_check)
ENTRY(spurious_interrupt_bug) ENTRY(spurious_interrupt_bug)
RING0_INT_FRAME RING0_INT_FRAME
ASM_CLAC
pushl_cfi $0 pushl_cfi $0
pushl_cfi $do_spurious_interrupt_bug pushl_cfi $do_spurious_interrupt_bug
jmp error_code jmp error_code
@ -1207,6 +1228,7 @@ return_to_handler:
ENTRY(page_fault) ENTRY(page_fault)
RING0_EC_FRAME RING0_EC_FRAME
ASM_CLAC
pushl_cfi $do_page_fault pushl_cfi $do_page_fault
ALIGN ALIGN
error_code: error_code:
@ -1279,6 +1301,7 @@ END(page_fault)
ENTRY(debug) ENTRY(debug)
RING0_INT_FRAME RING0_INT_FRAME
ASM_CLAC
cmpl $ia32_sysenter_target,(%esp) cmpl $ia32_sysenter_target,(%esp)
jne debug_stack_correct jne debug_stack_correct
FIX_STACK 12, debug_stack_correct, debug_esp_fix_insn FIX_STACK 12, debug_stack_correct, debug_esp_fix_insn
@ -1303,6 +1326,7 @@ END(debug)
*/ */
ENTRY(nmi) ENTRY(nmi)
RING0_INT_FRAME RING0_INT_FRAME
ASM_CLAC
pushl_cfi %eax pushl_cfi %eax
movl %ss, %eax movl %ss, %eax
cmpw $__ESPFIX_SS, %ax cmpw $__ESPFIX_SS, %ax
@ -1373,6 +1397,7 @@ END(nmi)
ENTRY(int3) ENTRY(int3)
RING0_INT_FRAME RING0_INT_FRAME
ASM_CLAC
pushl_cfi $-1 # mark this as an int pushl_cfi $-1 # mark this as an int
SAVE_ALL SAVE_ALL
TRACE_IRQS_OFF TRACE_IRQS_OFF
@ -1393,6 +1418,7 @@ END(general_protection)
#ifdef CONFIG_KVM_GUEST #ifdef CONFIG_KVM_GUEST
ENTRY(async_page_fault) ENTRY(async_page_fault)
RING0_EC_FRAME RING0_EC_FRAME
ASM_CLAC
pushl_cfi $do_async_page_fault pushl_cfi $do_async_page_fault
jmp error_code jmp error_code
CFI_ENDPROC CFI_ENDPROC