Skip to content

Commit 12e6590

Browse files
Marc Zyngieralex3788
authored andcommitted
FROMLIST: arm: Invalidate BTB on prefetch abort outside of user mapping on Cortex A8, A9, A12 and A17
In order to prevent aliasing attacks on the branch predictor, invalidate the BTB on CPUs that are known to be affected when taking a prefetch abort on a address that is outside of a user task limit. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> (cherry picked from git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git kpti commit a07373c8c365746583f25f49fee41b1bc0ff94b2) CVE-2017-5715 Change-Id: I6b0db5fbf1d495b03560b665dca37c2834d6f3a9 Signed-off-by: Tao Huang <huangtao@rock-chips.com> Reviewed-on: https://tp-biosrd-v02/gerrit/82397 Reviewed-by: Alex Cheng(鄭富元) <Alex_Cheng@asus.com> Tested-by: Alex Cheng(鄭富元) <Alex_Cheng@asus.com>
1 parent b7e02fc commit 12e6590

File tree

3 files changed

+93
-3
lines changed

3 files changed

+93
-3
lines changed

arch/arm/mm/fault.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/highmem.h>
2121
#include <linux/perf_event.h>
2222

23+
#include <asm/cp15.h>
2324
#include <asm/exception.h>
2425
#include <asm/pgtable.h>
2526
#include <asm/system_misc.h>
@@ -180,6 +181,7 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
180181
si.si_errno = 0;
181182
si.si_code = code;
182183
si.si_addr = (void __user *)addr;
184+
183185
force_sig_info(sig, &si, tsk);
184186
}
185187

@@ -395,12 +397,35 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
395397
__do_kernel_fault(mm, addr, fsr, regs);
396398
return 0;
397399
}
400+
401+
static int
402+
do_pabt_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
403+
{
404+
if (addr > TASK_SIZE) {
405+
switch(read_cpuid_part()) {
406+
case ARM_CPU_PART_CORTEX_A8:
407+
case ARM_CPU_PART_CORTEX_A9:
408+
case ARM_CPU_PART_CORTEX_A12:
409+
case ARM_CPU_PART_CORTEX_A17:
410+
asm volatile("mcr p15, 0, %0, c7, c5, 6" : : "r" (0));
411+
break;
412+
}
413+
}
414+
415+
return do_page_fault(addr, fsr, regs);
416+
}
398417
#else /* CONFIG_MMU */
399418
static int
400419
do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
401420
{
402421
return 0;
403422
}
423+
424+
static int
425+
do_pabt_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
426+
{
427+
return 0;
428+
}
404429
#endif /* CONFIG_MMU */
405430

406431
/*

arch/arm/mm/fsr-2level.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@ static struct fsr_info ifsr_info[] = {
5050
{ do_bad, SIGBUS, 0, "unknown 4" },
5151
{ do_translation_fault, SIGSEGV, SEGV_MAPERR, "section translation fault" },
5252
{ do_bad, SIGSEGV, SEGV_ACCERR, "page access flag fault" },
53-
{ do_page_fault, SIGSEGV, SEGV_MAPERR, "page translation fault" },
53+
{ do_pabt_page_fault, SIGSEGV, SEGV_MAPERR, "page translation fault" },
5454
{ do_bad, SIGBUS, 0, "external abort on non-linefetch" },
5555
{ do_bad, SIGSEGV, SEGV_ACCERR, "section domain fault" },
5656
{ do_bad, SIGBUS, 0, "unknown 10" },
5757
{ do_bad, SIGSEGV, SEGV_ACCERR, "page domain fault" },
5858
{ do_bad, SIGBUS, 0, "external abort on translation" },
5959
{ do_sect_fault, SIGSEGV, SEGV_ACCERR, "section permission fault" },
6060
{ do_bad, SIGBUS, 0, "external abort on translation" },
61-
{ do_page_fault, SIGSEGV, SEGV_ACCERR, "page permission fault" },
61+
{ do_pabt_page_fault, SIGSEGV, SEGV_ACCERR, "page permission fault" },
6262
{ do_bad, SIGBUS, 0, "unknown 16" },
6363
{ do_bad, SIGBUS, 0, "unknown 17" },
6464
{ do_bad, SIGBUS, 0, "unknown 18" },

arch/arm/mm/fsr-3level.c

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,69 @@ static struct fsr_info fsr_info[] = {
6565
{ do_bad, SIGBUS, 0, "unknown 63" },
6666
};
6767

68-
#define ifsr_info fsr_info
68+
static struct fsr_info ifsr_info[] = {
69+
{ do_bad, SIGBUS, 0, "unknown 0" },
70+
{ do_bad, SIGBUS, 0, "unknown 1" },
71+
{ do_bad, SIGBUS, 0, "unknown 2" },
72+
{ do_bad, SIGBUS, 0, "unknown 3" },
73+
{ do_bad, SIGBUS, 0, "reserved translation fault" },
74+
{ do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 1 translation fault" },
75+
{ do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 2 translation fault" },
76+
{ do_pabt_page_fault, SIGSEGV, SEGV_MAPERR, "level 3 translation fault" },
77+
{ do_bad, SIGBUS, 0, "reserved access flag fault" },
78+
{ do_bad, SIGSEGV, SEGV_ACCERR, "level 1 access flag fault" },
79+
{ do_pabt_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 access flag fault" },
80+
{ do_pabt_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 access flag fault" },
81+
{ do_bad, SIGBUS, 0, "reserved permission fault" },
82+
{ do_bad, SIGSEGV, SEGV_ACCERR, "level 1 permission fault" },
83+
{ do_pabt_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 permission fault" },
84+
{ do_pabt_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 permission fault" },
85+
{ do_bad, SIGBUS, 0, "synchronous external abort" },
86+
{ do_bad, SIGBUS, 0, "asynchronous external abort" },
87+
{ do_bad, SIGBUS, 0, "unknown 18" },
88+
{ do_bad, SIGBUS, 0, "unknown 19" },
89+
{ do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
90+
{ do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
91+
{ do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
92+
{ do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
93+
{ do_bad, SIGBUS, 0, "synchronous parity error" },
94+
{ do_bad, SIGBUS, 0, "asynchronous parity error" },
95+
{ do_bad, SIGBUS, 0, "unknown 26" },
96+
{ do_bad, SIGBUS, 0, "unknown 27" },
97+
{ do_bad, SIGBUS, 0, "synchronous parity error (translation table walk" },
98+
{ do_bad, SIGBUS, 0, "synchronous parity error (translation table walk" },
99+
{ do_bad, SIGBUS, 0, "synchronous parity error (translation table walk" },
100+
{ do_bad, SIGBUS, 0, "synchronous parity error (translation table walk" },
101+
{ do_bad, SIGBUS, 0, "unknown 32" },
102+
{ do_bad, SIGBUS, BUS_ADRALN, "alignment fault" },
103+
{ do_bad, SIGBUS, 0, "debug event" },
104+
{ do_bad, SIGBUS, 0, "unknown 35" },
105+
{ do_bad, SIGBUS, 0, "unknown 36" },
106+
{ do_bad, SIGBUS, 0, "unknown 37" },
107+
{ do_bad, SIGBUS, 0, "unknown 38" },
108+
{ do_bad, SIGBUS, 0, "unknown 39" },
109+
{ do_bad, SIGBUS, 0, "unknown 40" },
110+
{ do_bad, SIGBUS, 0, "unknown 41" },
111+
{ do_bad, SIGBUS, 0, "unknown 42" },
112+
{ do_bad, SIGBUS, 0, "unknown 43" },
113+
{ do_bad, SIGBUS, 0, "unknown 44" },
114+
{ do_bad, SIGBUS, 0, "unknown 45" },
115+
{ do_bad, SIGBUS, 0, "unknown 46" },
116+
{ do_bad, SIGBUS, 0, "unknown 47" },
117+
{ do_bad, SIGBUS, 0, "unknown 48" },
118+
{ do_bad, SIGBUS, 0, "unknown 49" },
119+
{ do_bad, SIGBUS, 0, "unknown 50" },
120+
{ do_bad, SIGBUS, 0, "unknown 51" },
121+
{ do_bad, SIGBUS, 0, "implementation fault (lockdown abort)" },
122+
{ do_bad, SIGBUS, 0, "unknown 53" },
123+
{ do_bad, SIGBUS, 0, "unknown 54" },
124+
{ do_bad, SIGBUS, 0, "unknown 55" },
125+
{ do_bad, SIGBUS, 0, "unknown 56" },
126+
{ do_bad, SIGBUS, 0, "unknown 57" },
127+
{ do_bad, SIGBUS, 0, "implementation fault (coprocessor abort)" },
128+
{ do_bad, SIGBUS, 0, "unknown 59" },
129+
{ do_bad, SIGBUS, 0, "unknown 60" },
130+
{ do_bad, SIGBUS, 0, "unknown 61" },
131+
{ do_bad, SIGBUS, 0, "unknown 62" },
132+
{ do_bad, SIGBUS, 0, "unknown 63" },
133+
};

0 commit comments

Comments
 (0)