Thu Apr 18 18:17:06 2024 UTC (22d)
Pull up following revision(s) (requested by skrll in ticket #667):

	sys/arch/aarch64/aarch64/sig_machdep.c: revision 1.9
	sys/arch/aarch64/aarch64/cpu_machdep.c: revision 1.15

kern/58149: aarch64: Cannot return from a signal handler if SP was
misaligned when the signal arrived

Apply the kernel diff from the PR
1. sendsig_siginfo() previously assumed that user SP was always aligned to
    16 bytes and could call signal handlers with SP misaligned. This is a
    wrong assumption because aarch64 demands that SP is aligned *only while*
    it's being used to access memory. Now it properly aligns it before
    pusing anything on the stack.
2. cpu_mcontext_validate() used to check if _REG_SP was aligned and
    considered the ucontext invalid otherwise. This meant if a signal was
    sent to a process whose SP was misaligned, the signal handler would fail
    to return because the ucontext passed from the kernel was an invalid
    one. Now setcontext(2) doesn't complain about misaligned SP.


(martin)
diff -r1.13 -r1.13.4.1 src/sys/arch/aarch64/aarch64/cpu_machdep.c
diff -r1.8 -r1.8.4.1 src/sys/arch/aarch64/aarch64/sig_machdep.c

cvs diff -r1.13 -r1.13.4.1 src/sys/arch/aarch64/aarch64/cpu_machdep.c (expand / switch to unified diff)

--- src/sys/arch/aarch64/aarch64/cpu_machdep.c 2022/07/28 09:14:12 1.13
+++ src/sys/arch/aarch64/aarch64/cpu_machdep.c 2024/04/18 18:17:06 1.13.4.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cpu_machdep.c,v 1.13 2022/07/28 09:14:12 riastradh Exp $ */ 1/* $NetBSD: cpu_machdep.c,v 1.13.4.1 2024/04/18 18:17:06 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2014, 2019 The NetBSD Foundation, Inc. 4 * Copyright (c) 2014, 2019 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry. 8 * by Matt Thomas of 3am Software Foundry.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33 33
34__KERNEL_RCSID(1, "$NetBSD: cpu_machdep.c,v 1.13 2022/07/28 09:14:12 riastradh Exp $"); 34__KERNEL_RCSID(1, "$NetBSD: cpu_machdep.c,v 1.13.4.1 2024/04/18 18:17:06 martin Exp $");
35 35
36#include "opt_multiprocessor.h" 36#include "opt_multiprocessor.h"
37 37
38#define _INTR_PRIVATE 38#define _INTR_PRIVATE
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/types.h> 41#include <sys/types.h>
42#include <sys/atomic.h> 42#include <sys/atomic.h>
43#include <sys/cpu.h> 43#include <sys/cpu.h>
44#include <sys/intr.h> 44#include <sys/intr.h>
45#include <sys/kmem.h> 45#include <sys/kmem.h>
46#include <sys/xcall.h> 46#include <sys/xcall.h>
47 47
@@ -146,29 +146,33 @@ dosoftints(void) @@ -146,29 +146,33 @@ dosoftints(void)
146 DOSOFTINT(NET); 146 DOSOFTINT(NET);
147 DOSOFTINT(BIO); 147 DOSOFTINT(BIO);
148 DOSOFTINT(CLOCK); 148 DOSOFTINT(CLOCK);
149 panic("dosoftints wtf (softints=%u?, ipl=%d)", softints, opl); 149 panic("dosoftints wtf (softints=%u?, ipl=%d)", softints, opl);
150 } 150 }
151 splx(s); 151 splx(s);
152} 152}
153#endif /* !__HAVE_PIC_FAST_SOFTINTS */ 153#endif /* !__HAVE_PIC_FAST_SOFTINTS */
154#endif /* __HAVE_FAST_SOFTINTS */ 154#endif /* __HAVE_FAST_SOFTINTS */
155 155
156int 156int
157cpu_mcontext_validate(struct lwp *l, const mcontext_t *mcp) 157cpu_mcontext_validate(struct lwp *l, const mcontext_t *mcp)
158{ 158{
 159 /*
 160 * We intentionally don't verify that _REG_SP is aligned to
 161 * 16-bytes boundaries because it can be legally misaligned as long
 162 * as it's not used for accessing memory.
 163 */
159 if ((mcp->__gregs[_REG_SPSR] & ~SPSR_NZCV) 164 if ((mcp->__gregs[_REG_SPSR] & ~SPSR_NZCV)
160 || (mcp->__gregs[_REG_PC] & 3) 165 || (mcp->__gregs[_REG_PC] & 3))
161 || (mcp->__gregs[_REG_SP] & 15)) 
162 return EINVAL; 166 return EINVAL;
163 167
164 return 0; 168 return 0;
165} 169}
166 170
167/* 171/*
168 * Since the ucontext_t will be on the stack most of the time, make sure 172 * Since the ucontext_t will be on the stack most of the time, make sure
169 * it will keep the stack aligned. 173 * it will keep the stack aligned.
170 */ 174 */
171CTASSERT(sizeof(ucontext_t) % 16 == 0); 175CTASSERT(sizeof(ucontext_t) % 16 == 0);
172 176
173CTASSERT(sizeof(struct reg) == sizeof(__gregset_t)); 177CTASSERT(sizeof(struct reg) == sizeof(__gregset_t));
174CTASSERT(offsetof(struct reg, r_pc) == _REG_PC * sizeof(__greg_t)); 178CTASSERT(offsetof(struct reg, r_pc) == _REG_PC * sizeof(__greg_t));

cvs diff -r1.8 -r1.8.4.1 src/sys/arch/aarch64/aarch64/sig_machdep.c (expand / switch to unified diff)

--- src/sys/arch/aarch64/aarch64/sig_machdep.c 2021/11/01 05:07:15 1.8
+++ src/sys/arch/aarch64/aarch64/sig_machdep.c 2024/04/18 18:17:06 1.8.4.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sig_machdep.c,v 1.8 2021/11/01 05:07:15 thorpej Exp $ */ 1/* $NetBSD: sig_machdep.c,v 1.8.4.1 2024/04/18 18:17:06 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2014 The NetBSD Foundation, Inc. 4 * Copyright (c) 2014 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry. 8 * by Matt Thomas of 3am Software Foundry.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -21,55 +21,61 @@ @@ -21,55 +21,61 @@
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33 33
34__KERNEL_RCSID(1, "$NetBSD: sig_machdep.c,v 1.8 2021/11/01 05:07:15 thorpej Exp $"); 34__KERNEL_RCSID(1, "$NetBSD: sig_machdep.c,v 1.8.4.1 2024/04/18 18:17:06 martin Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/types.h> 37#include <sys/types.h>
38#include <sys/cpu.h> 38#include <sys/cpu.h>
39#include <sys/proc.h> 39#include <sys/proc.h>
40#include <sys/signalvar.h> 40#include <sys/signalvar.h>
41#include <sys/siginfo.h> 41#include <sys/siginfo.h>
42 42
43#include <aarch64/frame.h> 43#include <aarch64/frame.h>
44 44
45void 45void
46sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask) 46sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
47{ 47{
48 struct lwp * const l = curlwp; 48 struct lwp * const l = curlwp;
49 struct proc * const p = l->l_proc; 49 struct proc * const p = l->l_proc;
50 struct trapframe * const tf = lwp_trapframe(l); 50 struct trapframe * const tf = lwp_trapframe(l);
51 stack_t * const ss = &l->l_sigstk; 51 stack_t * const ss = &l->l_sigstk;
52 const struct sigact_sigdesc * const sd = 52 const struct sigact_sigdesc * const sd =
53 &p->p_sigacts->sa_sigdesc[ksi->ksi_signo]; 53 &p->p_sigacts->sa_sigdesc[ksi->ksi_signo];
54 54
55 const uintptr_t handler = (uintptr_t) sd->sd_sigact.sa_handler; 55 const uintptr_t handler = (uintptr_t) sd->sd_sigact.sa_handler;
56 const bool onstack_p = (ss->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 56 const bool onstack_p = (ss->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0
57 && (sd->sd_sigact.sa_flags & SA_ONSTACK) != 0; 57 && (sd->sd_sigact.sa_flags & SA_ONSTACK) != 0;
58 58
59 vaddr_t sp; 59 vaddr_t sp;
60 60
61 sp = onstack_p ? ((vaddr_t)ss->ss_sp + ss->ss_size) & -16 : tf->tf_sp; 61 /*
 62 * The user stack isn't guaranteed to be aligned to 16 bytes. Align
 63 * it before pushing anything onto it.
 64 */
 65 sp = onstack_p ? ((vaddr_t)ss->ss_sp + ss->ss_size) : tf->tf_sp;
 66 sp &= -16;
62 67
 68 __CTASSERT(sizeof(ucontext_t) % 16 == 0);
63 sp -= sizeof(ucontext_t); 69 sp -= sizeof(ucontext_t);
64 const vaddr_t ucp = sp; 70 const vaddr_t ucp = sp;
65 71
66 sp -= roundup(sizeof(siginfo_t), 16); 72 sp -= roundup(sizeof(siginfo_t), 16);
67 const vaddr_t sip = sp; 73 const vaddr_t sip = sp;
68 74
69 ucontext_t uc; 75 ucontext_t uc;
70 memset(&uc, 0, sizeof(uc)); 76 memset(&uc, 0, sizeof(uc));
71 uc.uc_flags = _UC_SIGMASK; 77 uc.uc_flags = _UC_SIGMASK;
72 uc.uc_sigmask = *mask; 78 uc.uc_sigmask = *mask;
73 uc.uc_link = l->l_ctxlink; 79 uc.uc_link = l->l_ctxlink;
74 uc.uc_flags |= (l->l_sigstk.ss_flags & SS_ONSTACK) 80 uc.uc_flags |= (l->l_sigstk.ss_flags & SS_ONSTACK)
75 ? _UC_SETSTACK : _UC_CLRSTACK; 81 ? _UC_SETSTACK : _UC_CLRSTACK;