Skip to content

Commit 3dfffd5

Browse files
committed
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fixes from Will Deacon: "The important one is a change to the way in which we handle protection keys around signal delivery so that we're more closely aligned with the x86 behaviour, however there is also a revert of the previous fix to disable software tag-based KASAN with GCC, since a workaround materialised shortly afterwards. I'd love to say we're done with 6.12, but we're aware of some longstanding fpsimd register corruption issues that we're almost at the bottom of resolving. Summary: - Fix handling of POR_EL0 during signal delivery so that pushing the signal context doesn't fail based on the pkey configuration of the interrupted context and align our user-visible behaviour with that of x86. - Fix a bogus pointer being passed to the CPU hotplug code from the Arm SDEI driver. - Re-enable software tag-based KASAN with GCC by using an alternative implementation of '__no_sanitize_address'" * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: signal: Improve POR_EL0 handling to avoid uaccess failures firmware: arm_sdei: Fix the input parameter of cpuhp_remove_state() Revert "kasan: Disable Software Tag-Based KASAN with GCC" kasan: Fix Software Tag-Based KASAN with GCC
2 parents 17fa6a5 + 2e8a1ac commit 3dfffd5

File tree

4 files changed

+85
-20
lines changed

4 files changed

+85
-20
lines changed

arch/arm64/kernel/signal.c

+78-14
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/ratelimit.h>
2020
#include <linux/rseq.h>
2121
#include <linux/syscalls.h>
22+
#include <linux/pkeys.h>
2223

2324
#include <asm/daifflags.h>
2425
#include <asm/debug-monitors.h>
@@ -66,10 +67,63 @@ struct rt_sigframe_user_layout {
6667
unsigned long end_offset;
6768
};
6869

70+
/*
71+
* Holds any EL0-controlled state that influences unprivileged memory accesses.
72+
* This includes both accesses done in userspace and uaccess done in the kernel.
73+
*
74+
* This state needs to be carefully managed to ensure that it doesn't cause
75+
* uaccess to fail when setting up the signal frame, and the signal handler
76+
* itself also expects a well-defined state when entered.
77+
*/
78+
struct user_access_state {
79+
u64 por_el0;
80+
};
81+
6982
#define BASE_SIGFRAME_SIZE round_up(sizeof(struct rt_sigframe), 16)
7083
#define TERMINATOR_SIZE round_up(sizeof(struct _aarch64_ctx), 16)
7184
#define EXTRA_CONTEXT_SIZE round_up(sizeof(struct extra_context), 16)
7285

86+
/*
87+
* Save the user access state into ua_state and reset it to disable any
88+
* restrictions.
89+
*/
90+
static void save_reset_user_access_state(struct user_access_state *ua_state)
91+
{
92+
if (system_supports_poe()) {
93+
u64 por_enable_all = 0;
94+
95+
for (int pkey = 0; pkey < arch_max_pkey(); pkey++)
96+
por_enable_all |= POE_RXW << (pkey * POR_BITS_PER_PKEY);
97+
98+
ua_state->por_el0 = read_sysreg_s(SYS_POR_EL0);
99+
write_sysreg_s(por_enable_all, SYS_POR_EL0);
100+
/* Ensure that any subsequent uaccess observes the updated value */
101+
isb();
102+
}
103+
}
104+
105+
/*
106+
* Set the user access state for invoking the signal handler.
107+
*
108+
* No uaccess should be done after that function is called.
109+
*/
110+
static void set_handler_user_access_state(void)
111+
{
112+
if (system_supports_poe())
113+
write_sysreg_s(POR_EL0_INIT, SYS_POR_EL0);
114+
}
115+
116+
/*
117+
* Restore the user access state to the values saved in ua_state.
118+
*
119+
* No uaccess should be done after that function is called.
120+
*/
121+
static void restore_user_access_state(const struct user_access_state *ua_state)
122+
{
123+
if (system_supports_poe())
124+
write_sysreg_s(ua_state->por_el0, SYS_POR_EL0);
125+
}
126+
73127
static void init_user_layout(struct rt_sigframe_user_layout *user)
74128
{
75129
const size_t reserved_size =
@@ -261,18 +315,20 @@ static int restore_fpmr_context(struct user_ctxs *user)
261315
return err;
262316
}
263317

264-
static int preserve_poe_context(struct poe_context __user *ctx)
318+
static int preserve_poe_context(struct poe_context __user *ctx,
319+
const struct user_access_state *ua_state)
265320
{
266321
int err = 0;
267322

268323
__put_user_error(POE_MAGIC, &ctx->head.magic, err);
269324
__put_user_error(sizeof(*ctx), &ctx->head.size, err);
270-
__put_user_error(read_sysreg_s(SYS_POR_EL0), &ctx->por_el0, err);
325+
__put_user_error(ua_state->por_el0, &ctx->por_el0, err);
271326

272327
return err;
273328
}
274329

275-
static int restore_poe_context(struct user_ctxs *user)
330+
static int restore_poe_context(struct user_ctxs *user,
331+
struct user_access_state *ua_state)
276332
{
277333
u64 por_el0;
278334
int err = 0;
@@ -282,7 +338,7 @@ static int restore_poe_context(struct user_ctxs *user)
282338

283339
__get_user_error(por_el0, &(user->poe->por_el0), err);
284340
if (!err)
285-
write_sysreg_s(por_el0, SYS_POR_EL0);
341+
ua_state->por_el0 = por_el0;
286342

287343
return err;
288344
}
@@ -850,7 +906,8 @@ static int parse_user_sigframe(struct user_ctxs *user,
850906
}
851907

852908
static int restore_sigframe(struct pt_regs *regs,
853-
struct rt_sigframe __user *sf)
909+
struct rt_sigframe __user *sf,
910+
struct user_access_state *ua_state)
854911
{
855912
sigset_t set;
856913
int i, err;
@@ -899,7 +956,7 @@ static int restore_sigframe(struct pt_regs *regs,
899956
err = restore_zt_context(&user);
900957

901958
if (err == 0 && system_supports_poe() && user.poe)
902-
err = restore_poe_context(&user);
959+
err = restore_poe_context(&user, ua_state);
903960

904961
return err;
905962
}
@@ -908,6 +965,7 @@ SYSCALL_DEFINE0(rt_sigreturn)
908965
{
909966
struct pt_regs *regs = current_pt_regs();
910967
struct rt_sigframe __user *frame;
968+
struct user_access_state ua_state;
911969

912970
/* Always make any pending restarted system calls return -EINTR */
913971
current->restart_block.fn = do_no_restart_syscall;
@@ -924,12 +982,14 @@ SYSCALL_DEFINE0(rt_sigreturn)
924982
if (!access_ok(frame, sizeof (*frame)))
925983
goto badframe;
926984

927-
if (restore_sigframe(regs, frame))
985+
if (restore_sigframe(regs, frame, &ua_state))
928986
goto badframe;
929987

930988
if (restore_altstack(&frame->uc.uc_stack))
931989
goto badframe;
932990

991+
restore_user_access_state(&ua_state);
992+
933993
return regs->regs[0];
934994

935995
badframe:
@@ -1035,7 +1095,8 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
10351095
}
10361096

10371097
static int setup_sigframe(struct rt_sigframe_user_layout *user,
1038-
struct pt_regs *regs, sigset_t *set)
1098+
struct pt_regs *regs, sigset_t *set,
1099+
const struct user_access_state *ua_state)
10391100
{
10401101
int i, err = 0;
10411102
struct rt_sigframe __user *sf = user->sigframe;
@@ -1097,10 +1158,9 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,
10971158
struct poe_context __user *poe_ctx =
10981159
apply_user_offset(user, user->poe_offset);
10991160

1100-
err |= preserve_poe_context(poe_ctx);
1161+
err |= preserve_poe_context(poe_ctx, ua_state);
11011162
}
11021163

1103-
11041164
/* ZA state if present */
11051165
if (system_supports_sme() && err == 0 && user->za_offset) {
11061166
struct za_context __user *za_ctx =
@@ -1237,9 +1297,6 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
12371297
sme_smstop();
12381298
}
12391299

1240-
if (system_supports_poe())
1241-
write_sysreg_s(POR_EL0_INIT, SYS_POR_EL0);
1242-
12431300
if (ka->sa.sa_flags & SA_RESTORER)
12441301
sigtramp = ka->sa.sa_restorer;
12451302
else
@@ -1253,20 +1310,22 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
12531310
{
12541311
struct rt_sigframe_user_layout user;
12551312
struct rt_sigframe __user *frame;
1313+
struct user_access_state ua_state;
12561314
int err = 0;
12571315

12581316
fpsimd_signal_preserve_current_state();
12591317

12601318
if (get_sigframe(&user, ksig, regs))
12611319
return 1;
12621320

1321+
save_reset_user_access_state(&ua_state);
12631322
frame = user.sigframe;
12641323

12651324
__put_user_error(0, &frame->uc.uc_flags, err);
12661325
__put_user_error(NULL, &frame->uc.uc_link, err);
12671326

12681327
err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
1269-
err |= setup_sigframe(&user, regs, set);
1328+
err |= setup_sigframe(&user, regs, set, &ua_state);
12701329
if (err == 0) {
12711330
setup_return(regs, &ksig->ka, &user, usig);
12721331
if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
@@ -1276,6 +1335,11 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
12761335
}
12771336
}
12781337

1338+
if (err == 0)
1339+
set_handler_user_access_state();
1340+
else
1341+
restore_user_access_state(&ua_state);
1342+
12791343
return err;
12801344
}
12811345

drivers/firmware/arm_sdei.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@ static int sdei_device_freeze(struct device *dev)
763763
int err;
764764

765765
/* unregister private events */
766-
cpuhp_remove_state(sdei_entry_point);
766+
cpuhp_remove_state(sdei_hp_state);
767767

768768
err = sdei_unregister_shared();
769769
if (err)

include/linux/compiler-gcc.h

+4
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@
8080
#define __noscs __attribute__((__no_sanitize__("shadow-call-stack")))
8181
#endif
8282

83+
#ifdef __SANITIZE_HWADDRESS__
84+
#define __no_sanitize_address __attribute__((__no_sanitize__("hwaddress")))
85+
#else
8386
#define __no_sanitize_address __attribute__((__no_sanitize_address__))
87+
#endif
8488

8589
#if defined(__SANITIZE_THREAD__)
8690
#define __no_sanitize_thread __attribute__((__no_sanitize_thread__))

lib/Kconfig.kasan

+2-5
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@ config ARCH_DISABLE_KASAN_INLINE
2222
config CC_HAS_KASAN_GENERIC
2323
def_bool $(cc-option, -fsanitize=kernel-address)
2424

25-
# GCC appears to ignore no_sanitize_address when -fsanitize=kernel-hwaddress
26-
# is passed. See https://bugzilla.kernel.org/show_bug.cgi?id=218854 (and
27-
# the linked LKML thread) for more details.
2825
config CC_HAS_KASAN_SW_TAGS
29-
def_bool !CC_IS_GCC && $(cc-option, -fsanitize=kernel-hwaddress)
26+
def_bool $(cc-option, -fsanitize=kernel-hwaddress)
3027

3128
# This option is only required for software KASAN modes.
3229
# Old GCC versions do not have proper support for no_sanitize_address.
@@ -101,7 +98,7 @@ config KASAN_SW_TAGS
10198
help
10299
Enables Software Tag-Based KASAN.
103100

104-
Requires Clang.
101+
Requires GCC 11+ or Clang.
105102

106103
Supported only on arm64 CPUs and relies on Top Byte Ignore.
107104

0 commit comments

Comments
 (0)