Commit b226be50 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Marcelo Henrique Cerri

s390: add ppa to kernel entry / exit

CVE-2017-5754

BugLink: http://bugs.launchpad.net/bugs/1742771Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarAndy Whitcroft <apw@canonical.com>
parent 008e2cfd
...@@ -69,6 +69,7 @@ extern void s390_adjust_jiffies(void); ...@@ -69,6 +69,7 @@ extern void s390_adjust_jiffies(void);
extern const struct seq_operations cpuinfo_op; extern const struct seq_operations cpuinfo_op;
extern int sysctl_ieee_emulation_warnings; extern int sysctl_ieee_emulation_warnings;
extern void execve_tail(void); extern void execve_tail(void);
extern void __bpon(void);
/* /*
* User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit. * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit.
......
...@@ -14,6 +14,19 @@ static int __init disable_alternative_instructions(char *str) ...@@ -14,6 +14,19 @@ static int __init disable_alternative_instructions(char *str)
early_param("noaltinstr", disable_alternative_instructions); early_param("noaltinstr", disable_alternative_instructions);
extern struct alt_instr __alt_nobp[], __alt_nobp_end[];
static int __init nobp_setup(char *str)
{
bool enabled;
int rc;
rc = strtobool(str, &enabled);
if (!rc && enabled)
apply_alternatives(__alt_nobp, __alt_nobp_end);
return rc;
}
__setup("nobp=", nobp_setup);
struct brcl_insn { struct brcl_insn {
u16 opc; u16 opc;
s32 disp; s32 disp;
......
...@@ -162,8 +162,41 @@ _PIF_WORK = (_PIF_PER_TRAP) ...@@ -162,8 +162,41 @@ _PIF_WORK = (_PIF_PER_TRAP)
tm off+\addr, \mask tm off+\addr, \mask
.endm .endm
.macro BPOFF
.pushsection .altinstr_replacement, "ax"
660: .long 0xb2e8c000
.popsection
661: .long 0x47000000
.pushsection .altnobp, "a"
.long 661b - .
.long 660b - .
.word 82
.byte 4
.byte 4
.popsection
.endm
.macro BPON
.pushsection .altinstr_replacement, "ax"
662: .long 0xb2e8d000
.popsection
663: .long 0x47000000
.pushsection .altnobp, "a"
.long 663b - .
.long 662b - .
.word 82
.byte 4
.byte 4
.popsection
.endm
.section .kprobes.text, "ax" .section .kprobes.text, "ax"
ENTRY(__bpon)
.globl __bpon
BPON
br %r14
/* /*
* Scheduler resume function, called by switch_to * Scheduler resume function, called by switch_to
* gpr2 = (task_struct *) prev * gpr2 = (task_struct *) prev
...@@ -223,7 +256,9 @@ ENTRY(sie64a) ...@@ -223,7 +256,9 @@ ENTRY(sie64a)
jnz .Lsie_skip jnz .Lsie_skip
TSTMSK __LC_CPU_FLAGS,_CIF_FPU TSTMSK __LC_CPU_FLAGS,_CIF_FPU
jo .Lsie_skip # exit if fp/vx regs changed jo .Lsie_skip # exit if fp/vx regs changed
BPON
sie 0(%r14) sie 0(%r14)
BPOFF
.Lsie_skip: .Lsie_skip:
ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE
lctlg %c1,%c1,__LC_USER_ASCE # load primary asce lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
...@@ -267,6 +302,7 @@ ENTRY(system_call) ...@@ -267,6 +302,7 @@ ENTRY(system_call)
stpt __LC_SYNC_ENTER_TIMER stpt __LC_SYNC_ENTER_TIMER
.Lsysc_stmg: .Lsysc_stmg:
stmg %r8,%r15,__LC_SAVE_AREA_SYNC stmg %r8,%r15,__LC_SAVE_AREA_SYNC
BPOFF
lg %r10,__LC_LAST_BREAK lg %r10,__LC_LAST_BREAK
lg %r12,__LC_THREAD_INFO lg %r12,__LC_THREAD_INFO
lghi %r14,_PIF_SYSCALL lghi %r14,_PIF_SYSCALL
...@@ -311,6 +347,7 @@ ENTRY(system_call) ...@@ -311,6 +347,7 @@ ENTRY(system_call)
jnz .Lsysc_work # check for work jnz .Lsysc_work # check for work
TSTMSK __LC_CPU_FLAGS,_CIF_WORK TSTMSK __LC_CPU_FLAGS,_CIF_WORK
jnz .Lsysc_work jnz .Lsysc_work
BPON
.Lsysc_restore: .Lsysc_restore:
lg %r14,__LC_VDSO_PER_CPU lg %r14,__LC_VDSO_PER_CPU
lmg %r0,%r10,__PT_R0(%r11) lmg %r0,%r10,__PT_R0(%r11)
...@@ -471,6 +508,7 @@ ENTRY(kernel_thread_starter) ...@@ -471,6 +508,7 @@ ENTRY(kernel_thread_starter)
ENTRY(pgm_check_handler) ENTRY(pgm_check_handler)
stpt __LC_SYNC_ENTER_TIMER stpt __LC_SYNC_ENTER_TIMER
BPOFF
stmg %r8,%r15,__LC_SAVE_AREA_SYNC stmg %r8,%r15,__LC_SAVE_AREA_SYNC
lg %r10,__LC_LAST_BREAK lg %r10,__LC_LAST_BREAK
lg %r12,__LC_THREAD_INFO lg %r12,__LC_THREAD_INFO
...@@ -560,6 +598,7 @@ ENTRY(pgm_check_handler) ...@@ -560,6 +598,7 @@ ENTRY(pgm_check_handler)
ENTRY(io_int_handler) ENTRY(io_int_handler)
STCK __LC_INT_CLOCK STCK __LC_INT_CLOCK
stpt __LC_ASYNC_ENTER_TIMER stpt __LC_ASYNC_ENTER_TIMER
BPOFF
stmg %r8,%r15,__LC_SAVE_AREA_ASYNC stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
lg %r10,__LC_LAST_BREAK lg %r10,__LC_LAST_BREAK
lg %r12,__LC_THREAD_INFO lg %r12,__LC_THREAD_INFO
...@@ -601,9 +640,13 @@ ENTRY(io_int_handler) ...@@ -601,9 +640,13 @@ ENTRY(io_int_handler)
lg %r14,__LC_VDSO_PER_CPU lg %r14,__LC_VDSO_PER_CPU
lmg %r0,%r10,__PT_R0(%r11) lmg %r0,%r10,__PT_R0(%r11)
mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
tm __PT_PSW+1(%r11),0x01 # returning to user ?
jno .Lio_exit_kernel
BPON
.Lio_exit_timer: .Lio_exit_timer:
stpt __LC_EXIT_TIMER stpt __LC_EXIT_TIMER
mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
.Lio_exit_kernel:
lmg %r11,%r15,__PT_R11(%r11) lmg %r11,%r15,__PT_R11(%r11)
lpswe __LC_RETURN_PSW lpswe __LC_RETURN_PSW
.Lio_done: .Lio_done:
...@@ -735,6 +778,7 @@ ENTRY(io_int_handler) ...@@ -735,6 +778,7 @@ ENTRY(io_int_handler)
ENTRY(ext_int_handler) ENTRY(ext_int_handler)
STCK __LC_INT_CLOCK STCK __LC_INT_CLOCK
stpt __LC_ASYNC_ENTER_TIMER stpt __LC_ASYNC_ENTER_TIMER
BPOFF
stmg %r8,%r15,__LC_SAVE_AREA_ASYNC stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
lg %r10,__LC_LAST_BREAK lg %r10,__LC_LAST_BREAK
lg %r12,__LC_THREAD_INFO lg %r12,__LC_THREAD_INFO
...@@ -773,6 +817,7 @@ ENTRY(psw_idle) ...@@ -773,6 +817,7 @@ ENTRY(psw_idle)
.insn rsy,0xeb0000000017,%r1,5,__SF_EMPTY+16(%r15) .insn rsy,0xeb0000000017,%r1,5,__SF_EMPTY+16(%r15)
.Lpsw_idle_stcctm: .Lpsw_idle_stcctm:
#endif #endif
BPON
STCK __CLOCK_IDLE_ENTER(%r2) STCK __CLOCK_IDLE_ENTER(%r2)
stpt __TIMER_IDLE_ENTER(%r2) stpt __TIMER_IDLE_ENTER(%r2)
.Lpsw_idle_lpsw: .Lpsw_idle_lpsw:
...@@ -877,6 +922,7 @@ load_fpu_regs: ...@@ -877,6 +922,7 @@ load_fpu_regs:
*/ */
ENTRY(mcck_int_handler) ENTRY(mcck_int_handler)
STCK __LC_MCCK_CLOCK STCK __LC_MCCK_CLOCK
BPOFF
la %r1,4095 # revalidate r1 la %r1,4095 # revalidate r1
spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer
lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
...@@ -933,6 +979,7 @@ ENTRY(mcck_int_handler) ...@@ -933,6 +979,7 @@ ENTRY(mcck_int_handler)
mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
jno 0f jno 0f
BPON
stpt __LC_EXIT_TIMER stpt __LC_EXIT_TIMER
mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
0: lmg %r11,%r15,__PT_R11(%r11) 0: lmg %r11,%r15,__PT_R11(%r11)
......
...@@ -563,6 +563,7 @@ static struct kset *ipl_kset; ...@@ -563,6 +563,7 @@ static struct kset *ipl_kset;
static void __ipl_run(void *unused) static void __ipl_run(void *unused)
{ {
__bpon();
diag308(DIAG308_IPL, NULL); diag308(DIAG308_IPL, NULL);
if (MACHINE_IS_VM) if (MACHINE_IS_VM)
__cpcmd("IPL", NULL, 0, NULL); __cpcmd("IPL", NULL, 0, NULL);
......
...@@ -299,6 +299,7 @@ static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *), ...@@ -299,6 +299,7 @@ static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *),
mem_assign_absolute(lc->restart_fn, (unsigned long) func); mem_assign_absolute(lc->restart_fn, (unsigned long) func);
mem_assign_absolute(lc->restart_data, (unsigned long) data); mem_assign_absolute(lc->restart_data, (unsigned long) data);
mem_assign_absolute(lc->restart_source, source_cpu); mem_assign_absolute(lc->restart_source, source_cpu);
__bpon();
asm volatile( asm volatile(
"0: sigp 0,%0,%2 # sigp restart to target cpu\n" "0: sigp 0,%0,%2 # sigp restart to target cpu\n"
" brc 2,0b # busy, try again\n" " brc 2,0b # busy, try again\n"
...@@ -888,6 +889,7 @@ void __cpu_die(unsigned int cpu) ...@@ -888,6 +889,7 @@ void __cpu_die(unsigned int cpu)
void __noreturn cpu_die(void) void __noreturn cpu_die(void)
{ {
idle_task_exit(); idle_task_exit();
__bpon();
pcpu_sigp_retry(pcpu_devices + smp_processor_id(), SIGP_STOP, 0); pcpu_sigp_retry(pcpu_devices + smp_processor_id(), SIGP_STOP, 0);
for (;;) ; for (;;) ;
} }
......
...@@ -83,6 +83,9 @@ SECTIONS ...@@ -83,6 +83,9 @@ SECTIONS
__alt_instructions = .; __alt_instructions = .;
*(.altinstructions) *(.altinstructions)
__alt_instructions_end = .; __alt_instructions_end = .;
__alt_nobp = .;
*(.altnobp)
__alt_nobp_end = .;
} }
/* /*
......
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