Mon Apr 22 07:24:22 2024 UTC (17d)
Add a test for kern/58149

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


(pho)
diff -r1.1311 -r1.1312 src/distrib/sets/lists/tests/mi
diff -r1.77 -r1.78 src/tests/kernel/Makefile
diff -r0 -r1.1 src/tests/kernel/t_signal_and_sp.c
diff -r0 -r1.1 src/tests/kernel/arch/aarch64/stack_pointer.h

cvs diff -r1.1311 -r1.1312 src/distrib/sets/lists/tests/mi (expand / switch to unified diff)

--- src/distrib/sets/lists/tests/mi 2024/03/15 15:32:07 1.1311
+++ src/distrib/sets/lists/tests/mi 2024/04/22 07:24:22 1.1312
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: mi,v 1.1311 2024/03/15 15:32:07 riastradh Exp $ 1# $NetBSD: mi,v 1.1312 2024/04/22 07:24:22 pho Exp $
2# 2#
3# Note: don't delete entries from here - mark them as "obsolete" instead. 3# Note: don't delete entries from here - mark them as "obsolete" instead.
4# 4#
5./etc/mtree/set.tests tests-sys-root 5./etc/mtree/set.tests tests-sys-root
6./usr/libdata/debug/usr/tests tests-base-debug compattestdir 6./usr/libdata/debug/usr/tests tests-base-debug compattestdir
7./usr/libdata/debug/usr/tests/atf tests-atf-debug compattestfile,atf 7./usr/libdata/debug/usr/tests/atf tests-atf-debug compattestfile,atf
8./usr/libdata/debug/usr/tests/atf/atf-c tests-atf-debug compattestfile,atf 8./usr/libdata/debug/usr/tests/atf/atf-c tests-atf-debug compattestfile,atf
9./usr/libdata/debug/usr/tests/atf/atf-c++ tests-atf-debug compattestfile,atf 9./usr/libdata/debug/usr/tests/atf/atf-c++ tests-atf-debug compattestfile,atf
10./usr/libdata/debug/usr/tests/atf/atf-c++/detail tests-atf-debug compattestfile,atf 10./usr/libdata/debug/usr/tests/atf/atf-c++/detail tests-atf-debug compattestfile,atf
11./usr/libdata/debug/usr/tests/atf/atf-c/detail tests-atf-debug compattestfile,atf 11./usr/libdata/debug/usr/tests/atf/atf-c/detail tests-atf-debug compattestfile,atf
12./usr/libdata/debug/usr/tests/atf/atf-compile tests-obsolete obsolete 12./usr/libdata/debug/usr/tests/atf/atf-compile tests-obsolete obsolete
13./usr/libdata/debug/usr/tests/atf/atf-report tests-obsolete obsolete 13./usr/libdata/debug/usr/tests/atf/atf-report tests-obsolete obsolete
14./usr/libdata/debug/usr/tests/atf/atf-run tests-obsolete obsolete 14./usr/libdata/debug/usr/tests/atf/atf-run tests-obsolete obsolete
@@ -2337,26 +2337,27 @@ @@ -2337,26 +2337,27 @@
2337./usr/tests/kernel/t_proccwd tests-kernel-tests compattestfile,atf 2337./usr/tests/kernel/t_proccwd tests-kernel-tests compattestfile,atf
2338./usr/tests/kernel/t_procpath tests-kernel-tests compattestfile,atf 2338./usr/tests/kernel/t_procpath tests-kernel-tests compattestfile,atf
2339./usr/tests/kernel/t_ps_strings tests-kernel-tests compattestfile,atf 2339./usr/tests/kernel/t_ps_strings tests-kernel-tests compattestfile,atf
2340./usr/tests/kernel/t_ptrace tests-obsolete obsolete 2340./usr/tests/kernel/t_ptrace tests-obsolete obsolete
2341./usr/tests/kernel/t_ptrace_wait tests-obsolete obsolete 2341./usr/tests/kernel/t_ptrace_wait tests-obsolete obsolete
2342./usr/tests/kernel/t_ptrace_wait3 tests-obsolete obsolete 2342./usr/tests/kernel/t_ptrace_wait3 tests-obsolete obsolete
2343./usr/tests/kernel/t_ptrace_wait4 tests-obsolete obsolete 2343./usr/tests/kernel/t_ptrace_wait4 tests-obsolete obsolete
2344./usr/tests/kernel/t_ptrace_wait6 tests-obsolete obsolete 2344./usr/tests/kernel/t_ptrace_wait6 tests-obsolete obsolete
2345./usr/tests/kernel/t_ptrace_waitid tests-obsolete obsolete 2345./usr/tests/kernel/t_ptrace_waitid tests-obsolete obsolete
2346./usr/tests/kernel/t_ptrace_waitpid tests-obsolete obsolete 2346./usr/tests/kernel/t_ptrace_waitpid tests-obsolete obsolete
2347./usr/tests/kernel/t_pty tests-kernel-tests compattestfile,atf 2347./usr/tests/kernel/t_pty tests-kernel-tests compattestfile,atf
2348./usr/tests/kernel/t_rnd tests-kernel-tests atf,rump 2348./usr/tests/kernel/t_rnd tests-kernel-tests atf,rump
2349./usr/tests/kernel/t_sigaction tests-obsolete obsolete 2349./usr/tests/kernel/t_sigaction tests-obsolete obsolete
 2350./usr/tests/kernel/t_signal_and_sp tests-kernel-tests compattestfile,atf
2350./usr/tests/kernel/t_simplehook tests-kernel-tests atf,rump 2351./usr/tests/kernel/t_simplehook tests-kernel-tests atf,rump
2351./usr/tests/kernel/t_subr_prf tests-kernel-tests compattestfile,atf 2352./usr/tests/kernel/t_subr_prf tests-kernel-tests compattestfile,atf
2352./usr/tests/kernel/t_sysctl tests-kernel-tests compattestfile,atf 2353./usr/tests/kernel/t_sysctl tests-kernel-tests compattestfile,atf
2353./usr/tests/kernel/t_sysv tests-kernel-tests compattestfile,atf 2354./usr/tests/kernel/t_sysv tests-kernel-tests compattestfile,atf
2354./usr/tests/kernel/t_time tests-obsolete obsolete 2355./usr/tests/kernel/t_time tests-obsolete obsolete
2355./usr/tests/kernel/t_timeleft tests-kernel-tests compattestfile,atf 2356./usr/tests/kernel/t_timeleft tests-kernel-tests compattestfile,atf
2356./usr/tests/kernel/t_trapsignal tests-kernel-tests compattestfile,atf 2357./usr/tests/kernel/t_trapsignal tests-kernel-tests compattestfile,atf
2357./usr/tests/kernel/t_ucontext tests-obsolete obsolete 2358./usr/tests/kernel/t_ucontext tests-obsolete obsolete
2358./usr/tests/kernel/t_umount tests-kernel-tests compattestfile,atf 2359./usr/tests/kernel/t_umount tests-kernel-tests compattestfile,atf
2359./usr/tests/kernel/t_umountstress tests-kernel-tests compattestfile,atf 2360./usr/tests/kernel/t_umountstress tests-kernel-tests compattestfile,atf
2360./usr/tests/kernel/t_writev tests-obsolete obsolete 2361./usr/tests/kernel/t_writev tests-obsolete obsolete
2361./usr/tests/kernel/t_zombie tests-kernel-tests compattestfile,atf 2362./usr/tests/kernel/t_zombie tests-kernel-tests compattestfile,atf
2362./usr/tests/kernel/tty tests-kernel-tests compattestfile,atf 2363./usr/tests/kernel/tty tests-kernel-tests compattestfile,atf

cvs diff -r1.77 -r1.78 src/tests/kernel/Makefile (expand / switch to unified diff)

--- src/tests/kernel/Makefile 2023/10/17 13:51:52 1.77
+++ src/tests/kernel/Makefile 2024/04/22 07:24:22 1.78
@@ -1,33 +1,34 @@ @@ -1,33 +1,34 @@
1# $NetBSD: Makefile,v 1.77 2023/10/17 13:51:52 rjs Exp $ 1# $NetBSD: Makefile,v 1.78 2024/04/22 07:24:22 pho Exp $
2 2
3NOMAN= # defined 3NOMAN= # defined
4 4
5.include <bsd.own.mk> 5.include <bsd.own.mk>
6 6
7TESTSDIR= ${TESTSBASE}/kernel 7TESTSDIR= ${TESTSBASE}/kernel
8 8
9TESTS_SUBDIRS+= kqueue 9TESTS_SUBDIRS+= kqueue
10#TESTS_C= t_epoll 10#TESTS_C= t_epoll
11TESTS_C+= t_fcntl 11TESTS_C+= t_fcntl
12.if ${MKRUMP} != "no" 12.if ${MKRUMP} != "no"
13TESTS_C+= t_fdrestart 13TESTS_C+= t_fdrestart
14.endif 14.endif
15TESTS_C+= t_lock 15TESTS_C+= t_lock
16TESTS_C+= t_lockf 16TESTS_C+= t_lockf
17TESTS_C+= t_pty 17TESTS_C+= t_pty
18TESTS_C+= t_memfd_create 18TESTS_C+= t_memfd_create
19TESTS_C+= t_mqueue 19TESTS_C+= t_mqueue
20TESTS_C+= t_proccwd 20TESTS_C+= t_proccwd
 21TESTS_C+= t_signal_and_sp
21TESTS_C+= t_sysv 22TESTS_C+= t_sysv
22TESTS_C+= t_subr_prf 23TESTS_C+= t_subr_prf
23TESTS_C+= t_kauth_pr_47598 24TESTS_C+= t_kauth_pr_47598
24TESTS_C+= t_ksem 25TESTS_C+= t_ksem
25TESTS_C+= t_sysctl 26TESTS_C+= t_sysctl
26TESTS_C+= t_timeleft 27TESTS_C+= t_timeleft
27TESTS_C+= t_zombie 28TESTS_C+= t_zombie
28TESTS_C+= t_open_pr_57260 29TESTS_C+= t_open_pr_57260
29 30
30TESTS_SH= t_umount 31TESTS_SH= t_umount
31TESTS_SH+= t_umountstress 32TESTS_SH+= t_umountstress
32TESTS_SH+= t_ps_strings 33TESTS_SH+= t_ps_strings
33TESTS_SH+= t_trapsignal 34TESTS_SH+= t_trapsignal
@@ -69,26 +70,31 @@ TESTS_SUBDIRS+= tty @@ -69,26 +70,31 @@ TESTS_SUBDIRS+= tty
69TESTS_C+= t_extattrctl 70TESTS_C+= t_extattrctl
70TESTS_C+= t_filedesc 71TESTS_C+= t_filedesc
71TESTS_C+= t_rnd 72TESTS_C+= t_rnd
72LDADD.t_extattrctl+= ${LIBRUMPBASE} 73LDADD.t_extattrctl+= ${LIBRUMPBASE}
73LDADD.t_filedesc+= ${LDADD.t_rnd} 74LDADD.t_filedesc+= ${LDADD.t_rnd}
74LDADD.t_rnd+= -lrumpdev_rnd -lrumpdev ${LIBRUMPBASE} 75LDADD.t_rnd+= -lrumpdev_rnd -lrumpdev ${LIBRUMPBASE}
75 76
76.endif 77.endif
77 78
78LDADD.t_timeleft+= -lpthread 79LDADD.t_timeleft+= -lpthread
79 80
80CPPFLAGS+= -D_KERNTYPES 81CPPFLAGS+= -D_KERNTYPES
81 82
 83ARCH_INCS_DIR:= ${.PARSEDIR}/arch/${MACHINE_ARCH}
 84.if exists(${ARCH_INCS_DIR}/stack_pointer.h)
 85CPPFLAGS+= -I${ARCH_INCS_DIR} -DHAVE_STACK_POINTER_H
 86.endif
 87
82.PATH: ${NETBSDSRCDIR}/sys/kern 88.PATH: ${NETBSDSRCDIR}/sys/kern
83TESTS_C+= t_extent 89TESTS_C+= t_extent
84SRCS.t_extent= t_extent.c subr_extent.c 90SRCS.t_extent= t_extent.c subr_extent.c
85CPPFLAGS.t_extent.c= -D_EXTENT_TESTING -D__POOL_EXPOSE -D_KERNTYPES 91CPPFLAGS.t_extent.c= -D_EXTENT_TESTING -D__POOL_EXPOSE -D_KERNTYPES
86CPPFLAGS.subr_extent.c= -D_EXTENT_TESTING -D__POOL_EXPOSE -D_KERNTYPES 92CPPFLAGS.subr_extent.c= -D_EXTENT_TESTING -D__POOL_EXPOSE -D_KERNTYPES
87 93
88t_subr_prf.c: gen_t_subr_prf ${NETBSDSRCDIR}/sys/kern/subr_prf.c 94t_subr_prf.c: gen_t_subr_prf ${NETBSDSRCDIR}/sys/kern/subr_prf.c
89 ${HOST_SH} ${.ALLSRC} ${.TARGET} 95 ${HOST_SH} ${.ALLSRC} ${.TARGET}
90.if ${MKSANITIZER:Uno} == "yes" 96.if ${MKSANITIZER:Uno} == "yes"
91 # These symbols will be redefined by MKSANITIZER 97 # These symbols will be redefined by MKSANITIZER
92 ${TOOL_SED} -i '/undef .*printf/d' ${.TARGET} 98 ${TOOL_SED} -i '/undef .*printf/d' ${.TARGET}
93.endif 99.endif
94 100

File Added: src/tests/kernel/t_signal_and_sp.c
/* $NetBSD: t_signal_and_sp.c,v 1.1 2024/04/22 07:24:22 pho Exp $ */

/*
 * Copyright (c) 2024 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <atf-c.h>

#if defined(HAVE_STACK_POINTER_H)
#  include <signal.h>
#  include <string.h>
#  include <sys/stdint.h>
#  include <sys/time.h>
#  include "stack_pointer.h"

static volatile void* stack_pointer = NULL;
static void on_alarm(int sig __attribute__((__unused__)))
{
	/*
	 * Store the stack pointer into a variable so that we can test if
	 * it's aligned.
	 */
	LOAD_SP(stack_pointer);

	/*
	 * Now we are going to return from a signal
	 * handler. __sigtramp_siginfo_2 will call setcontext(2) with a
	 * ucontext provided by the kernel. When that fails it will call
	 * _Exit(2) with the errno, and the test will fail.
	 */
}
#endif

ATF_TC(misaligned_sp_and_signal);
ATF_TC_HEAD(misaligned_sp_and_signal, tc)
{
	atf_tc_set_md_var(tc, "descr", "process can return from a signal"
	    " handler even if the stack pointer is misaligned when a signal"
	    " arrives");
}
ATF_TC_BODY(misaligned_sp_and_signal, tc)
{
#if defined(HAVE_STACK_POINTER_H)
	/*
	 * Set up a handler for SIGALRM.
	 */
	struct sigaction sa;
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = &on_alarm;
	ATF_REQUIRE(sigaction(SIGALRM, &sa, NULL) == 0);

	/*
	 * Set up an interval timer so that we receive SIGALRM after 50 ms.
	 */
	struct itimerval itv;
	memset(&itv, 0, sizeof(itv));
	itv.it_value.tv_usec = 1000 * 50;
	ATF_REQUIRE(setitimer(ITIMER_MONOTONIC, &itv, NULL) == 0);

	/*
	 * Now misalign the SP. Wait for the signal to arrive and see what
	 * happens. This should be fine as long as we don't use it to
	 * access memory.
	 */
	MISALIGN_SP;
	while (stack_pointer == NULL) {
		/*
		 * Make sure the compiler does not optimize this busy loop
		 * away.
		 */
		__asm__("" : : : "memory");
	}
	/*
	 * We could successfully return from a signal handler. Now we
	 * should fix the SP before calling any functions.
	 */
	FIX_SP;

	/*
	 * But was the stack pointer aligned when we were on the signal
	 * handler?
	 */
	ATF_CHECK_MSG(is_sp_aligned((uintptr_t)stack_pointer),
	    "signal handler was called with a misaligned sp: %p",
	    stack_pointer);
#else
	atf_tc_skip("Not implemented for this platform");
#endif
}

ATF_TP_ADD_TCS(tp)
{
	ATF_TP_ADD_TC(tp, misaligned_sp_and_signal);
	return atf_no_error();
}

File Added: src/tests/kernel/arch/aarch64/stack_pointer.h
/* $NetBSD: stack_pointer.h,v 1.1 2024/04/22 07:24:22 pho Exp $ */

/*
 * Copyright (c) 2024 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/stdbool.h>
#include <sys/stdint.h>

#define LOAD_SP(var)					\
	do {						\
		register void* tmp __asm__("x0");	\
		__asm__(				\
			"mov %0, sp"			\
			: "=r"(tmp)			\
		);					\
		(var) = tmp;				\
	} while (0)

#define MISALIGN_SP				\
	__asm__ volatile (			\
		"sub sp, sp, #8"		\
	)

#define FIX_SP					\
	__asm__ volatile (			\
		"add sp, sp, #8"		\
	)

static inline bool
is_sp_aligned(uintptr_t sp)
{
	return sp % 16 == 0;
}