Skip to content

Commit 1b7eaf5

Browse files
committed
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fixes from Catalin Marinas: - It turns out that the optimised string routines merged in 5.14 are not safe with in-kernel MTE (KASAN_HW_TAGS) because of reading beyond the end of a string (strcmp, strncmp). Such reading may go across a 16 byte tag granule and cause a tag check fault. When KASAN_HW_TAGS is enabled, use the generic strcmp/strncmp C implementation. - An errata workaround for ThunderX relied on the CPU capabilities being enabled in a specific order. This disappeared with the automatic generation of the cpucaps.h file (sorted alphabetically). Fix it by checking the current CPU only rather than the system-wide capability. - Add system_supports_mte() checks on the kernel entry/exit path and thread switching to avoid unnecessary barriers and function calls on systems where MTE is not supported. - kselftests: skip arm64 tests if the required features are missing. * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: Restore forced disabling of KPTI on ThunderX kselftest/arm64: signal: Skip tests if required features are missing arm64: Mitigate MTE issues with str{n}cmp() arm64: add MTE supported check to thread switching and syscall entry/exit
2 parents 4c4f0c2 + 22b70e6 commit 1b7eaf5

File tree

8 files changed

+30
-12
lines changed

8 files changed

+30
-12
lines changed

arch/arm64/include/asm/assembler.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,11 @@ alternative_endif
525525
#define EXPORT_SYMBOL_NOKASAN(name) EXPORT_SYMBOL(name)
526526
#endif
527527

528+
#ifdef CONFIG_KASAN_HW_TAGS
529+
#define EXPORT_SYMBOL_NOHWKASAN(name)
530+
#else
531+
#define EXPORT_SYMBOL_NOHWKASAN(name) EXPORT_SYMBOL_NOKASAN(name)
532+
#endif
528533
/*
529534
* Emit a 64-bit absolute little endian symbol reference in a way that
530535
* ensures that it will be resolved at build time, even when building a

arch/arm64/include/asm/mte.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,17 @@ void mte_check_tfsr_el1(void);
9999

100100
static inline void mte_check_tfsr_entry(void)
101101
{
102+
if (!system_supports_mte())
103+
return;
104+
102105
mte_check_tfsr_el1();
103106
}
104107

105108
static inline void mte_check_tfsr_exit(void)
106109
{
110+
if (!system_supports_mte())
111+
return;
112+
107113
/*
108114
* The asynchronous faults are sync'ed automatically with
109115
* TFSR_EL1 on kernel entry but for exit an explicit dsb()

arch/arm64/include/asm/string.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ extern char *strrchr(const char *, int c);
1212
#define __HAVE_ARCH_STRCHR
1313
extern char *strchr(const char *, int c);
1414

15+
#ifndef CONFIG_KASAN_HW_TAGS
1516
#define __HAVE_ARCH_STRCMP
1617
extern int strcmp(const char *, const char *);
1718

1819
#define __HAVE_ARCH_STRNCMP
1920
extern int strncmp(const char *, const char *, __kernel_size_t);
21+
#endif
2022

2123
#define __HAVE_ARCH_STRLEN
2224
extern __kernel_size_t strlen(const char *);

arch/arm64/kernel/cpufeature.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,9 +1526,13 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
15261526
/*
15271527
* For reasons that aren't entirely clear, enabling KPTI on Cavium
15281528
* ThunderX leads to apparent I-cache corruption of kernel text, which
1529-
* ends as well as you might imagine. Don't even try.
1529+
* ends as well as you might imagine. Don't even try. We cannot rely
1530+
* on the cpus_have_*cap() helpers here to detect the CPU erratum
1531+
* because cpucap detection order may change. However, since we know
1532+
* affected CPUs are always in a homogeneous configuration, it is
1533+
* safe to rely on this_cpu_has_cap() here.
15301534
*/
1531-
if (cpus_have_const_cap(ARM64_WORKAROUND_CAVIUM_27456)) {
1535+
if (this_cpu_has_cap(ARM64_WORKAROUND_CAVIUM_27456)) {
15321536
str = "ARM64_WORKAROUND_CAVIUM_27456";
15331537
__kpti_forced = -1;
15341538
}

arch/arm64/kernel/mte.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,7 @@ void mte_enable_kernel_async(void)
142142
#ifdef CONFIG_KASAN_HW_TAGS
143143
void mte_check_tfsr_el1(void)
144144
{
145-
u64 tfsr_el1;
146-
147-
if (!system_supports_mte())
148-
return;
149-
150-
tfsr_el1 = read_sysreg_s(SYS_TFSR_EL1);
145+
u64 tfsr_el1 = read_sysreg_s(SYS_TFSR_EL1);
151146

152147
if (unlikely(tfsr_el1 & SYS_TFSR_EL1_TF1)) {
153148
/*
@@ -199,6 +194,9 @@ void mte_thread_init_user(void)
199194

200195
void mte_thread_switch(struct task_struct *next)
201196
{
197+
if (!system_supports_mte())
198+
return;
199+
202200
mte_update_sctlr_user(next);
203201

204202
/*

arch/arm64/lib/strcmp.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,4 @@ L(done):
173173
ret
174174

175175
SYM_FUNC_END_PI(strcmp)
176-
EXPORT_SYMBOL_NOKASAN(strcmp)
176+
EXPORT_SYMBOL_NOHWKASAN(strcmp)

arch/arm64/lib/strncmp.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,4 +258,4 @@ L(ret0):
258258
ret
259259

260260
SYM_FUNC_END_PI(strncmp)
261-
EXPORT_SYMBOL_NOKASAN(strncmp)
261+
EXPORT_SYMBOL_NOHWKASAN(strncmp)

tools/testing/selftests/arm64/signal/test_signals_utils.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,16 +266,19 @@ int test_init(struct tdescr *td)
266266
td->feats_supported |= FEAT_SSBS;
267267
if (getauxval(AT_HWCAP) & HWCAP_SVE)
268268
td->feats_supported |= FEAT_SVE;
269-
if (feats_ok(td))
269+
if (feats_ok(td)) {
270270
fprintf(stderr,
271271
"Required Features: [%s] supported\n",
272272
feats_to_string(td->feats_required &
273273
td->feats_supported));
274-
else
274+
} else {
275275
fprintf(stderr,
276276
"Required Features: [%s] NOT supported\n",
277277
feats_to_string(td->feats_required &
278278
~td->feats_supported));
279+
td->result = KSFT_SKIP;
280+
return 0;
281+
}
279282
}
280283

281284
/* Perform test specific additional initialization */

0 commit comments

Comments
 (0)