hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/arch/arm64/kernel/signal.c
....@@ -1,20 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Based on arch/arm/kernel/signal.c
34 *
45 * Copyright (C) 1995-2009 Russell King
56 * Copyright (C) 2012 ARM Ltd.
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License version 2 as
9
- * published by the Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
187 */
198
209 #include <linux/cache.h>
....@@ -40,6 +29,7 @@
4029 #include <asm/unistd.h>
4130 #include <asm/fpsimd.h>
4231 #include <asm/ptrace.h>
32
+#include <asm/syscall.h>
4333 #include <asm/signal32.h>
4434 #include <asm/traps.h>
4535 #include <asm/vdso.h>
....@@ -255,7 +245,8 @@
255245 if (vq) {
256246 /*
257247 * This assumes that the SVE state has already been saved to
258
- * the task struct by calling preserve_fpsimd_context().
248
+ * the task struct by calling the function
249
+ * fpsimd_signal_preserve_current_state().
259250 */
260251 err |= __copy_to_user((char __user *)ctx + SVE_SIG_REGS_OFFSET,
261252 current->thread.sve_state,
....@@ -296,11 +287,6 @@
296287 */
297288
298289 fpsimd_flush_task_state(current);
299
- barrier();
300
- /* From now, fpsimd_thread_switch() won't clear TIF_FOREIGN_FPSTATE */
301
-
302
- set_thread_flag(TIF_FOREIGN_FPSTATE);
303
- barrier();
304290 /* From now, fpsimd_thread_switch() won't touch thread.sve_state */
305291
306292 sve_alloc(current);
....@@ -387,6 +373,8 @@
387373 goto done;
388374
389375 case FPSIMD_MAGIC:
376
+ if (!system_supports_fpsimd())
377
+ goto invalid;
390378 if (user->fpsimd)
391379 goto invalid;
392380
....@@ -470,7 +458,7 @@
470458 offset = 0;
471459 limit = extra_size;
472460
473
- if (!access_ok(VERIFY_READ, base, limit))
461
+ if (!access_ok(base, limit))
474462 goto invalid;
475463
476464 continue;
....@@ -522,7 +510,7 @@
522510 if (err == 0)
523511 err = parse_user_sigframe(&user, sf);
524512
525
- if (err == 0) {
513
+ if (err == 0 && system_supports_fpsimd()) {
526514 if (!user.fpsimd)
527515 return -EINVAL;
528516
....@@ -556,7 +544,7 @@
556544
557545 frame = (struct rt_sigframe __user *)regs->sp;
558546
559
- if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
547
+ if (!access_ok(frame, sizeof (*frame)))
560548 goto badframe;
561549
562550 if (restore_sigframe(regs, frame))
....@@ -584,10 +572,12 @@
584572 {
585573 int err;
586574
587
- err = sigframe_alloc(user, &user->fpsimd_offset,
588
- sizeof(struct fpsimd_context));
589
- if (err)
590
- return err;
575
+ if (system_supports_fpsimd()) {
576
+ err = sigframe_alloc(user, &user->fpsimd_offset,
577
+ sizeof(struct fpsimd_context));
578
+ if (err)
579
+ return err;
580
+ }
591581
592582 /* fault information, if valid */
593583 if (add_all || current->thread.fault_code) {
....@@ -639,7 +629,7 @@
639629
640630 err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
641631
642
- if (err == 0) {
632
+ if (err == 0 && system_supports_fpsimd()) {
643633 struct fpsimd_context __user *fpsimd_ctx =
644634 apply_user_offset(user, user->fpsimd_offset);
645635 err |= preserve_fpsimd_context(fpsimd_ctx);
....@@ -730,7 +720,7 @@
730720 /*
731721 * Check that we can actually write to the signal frame.
732722 */
733
- if (!access_ok(VERIFY_WRITE, user->sigframe, sp_top - sp))
723
+ if (!access_ok(user->sigframe, sp_top - sp))
734724 return -EFAULT;
735725
736726 return 0;
....@@ -745,6 +735,25 @@
745735 regs->sp = (unsigned long)user->sigframe;
746736 regs->regs[29] = (unsigned long)&user->next_frame->fp;
747737 regs->pc = (unsigned long)ka->sa.sa_handler;
738
+
739
+ /*
740
+ * Signal delivery is a (wacky) indirect function call in
741
+ * userspace, so simulate the same setting of BTYPE as a BLR
742
+ * <register containing the signal handler entry point>.
743
+ * Signal delivery to a location in a PROT_BTI guarded page
744
+ * that is not a function entry point will now trigger a
745
+ * SIGILL in userspace.
746
+ *
747
+ * If the signal handler entry point is not in a PROT_BTI
748
+ * guarded page, this is harmless.
749
+ */
750
+ if (system_supports_bti()) {
751
+ regs->pstate &= ~PSR_BTYPE_MASK;
752
+ regs->pstate |= PSR_BTYPE_C;
753
+ }
754
+
755
+ /* TCO (Tag Check Override) always cleared for signal handlers */
756
+ regs->pstate &= ~PSR_TCO_BIT;
748757
749758 if (ka->sa.sa_flags & SA_RESTORER)
750759 sigtramp = ka->sa.sa_restorer;
....@@ -884,7 +893,7 @@
884893 retval == -ERESTART_RESTARTBLOCK ||
885894 (retval == -ERESTARTSYS &&
886895 !(ksig.ka.sa.sa_flags & SA_RESTART)))) {
887
- regs->regs[0] = -EINTR;
896
+ syscall_set_return_value(current, regs, -EINTR, 0);
888897 regs->pc = continue_addr;
889898 }
890899
....@@ -908,18 +917,11 @@
908917 asmlinkage void do_notify_resume(struct pt_regs *regs,
909918 unsigned long thread_flags)
910919 {
911
- /*
912
- * The assembly code enters us with IRQs off, but it hasn't
913
- * informed the tracing code of that for efficiency reasons.
914
- * Update the trace code with the current status.
915
- */
916
- trace_hardirqs_off();
917
-
918920 do {
919921 /* Check valid user FS if needed */
920922 addr_limit_user_check();
921923
922
- if (thread_flags & _TIF_NEED_RESCHED_MASK) {
924
+ if (thread_flags & _TIF_NEED_RESCHED) {
923925 /* Unmask Debug and SError for the next task */
924926 local_daif_restore(DAIF_PROCCTX_NOIRQ);
925927
....@@ -930,11 +932,16 @@
930932 if (thread_flags & _TIF_UPROBE)
931933 uprobe_notify_resume(regs);
932934
933
- if (thread_flags & _TIF_SIGPENDING)
935
+ if (thread_flags & _TIF_MTE_ASYNC_FAULT) {
936
+ clear_thread_flag(TIF_MTE_ASYNC_FAULT);
937
+ send_sig_fault(SIGSEGV, SEGV_MTEAERR,
938
+ (void __user *)NULL, current);
939
+ }
940
+
941
+ if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
934942 do_signal(regs);
935943
936944 if (thread_flags & _TIF_NOTIFY_RESUME) {
937
- clear_thread_flag(TIF_NOTIFY_RESUME);
938945 tracehook_notify_resume(regs);
939946 rseq_handle_notify_resume(NULL, regs);
940947 }