Home | History | Annotate | Line # | Download | only in kernel
t_signal_and_sp.c revision 1.1
      1  1.1  pho /* $NetBSD: t_signal_and_sp.c,v 1.1 2024/04/22 07:24:22 pho Exp $ */
      2  1.1  pho 
      3  1.1  pho /*
      4  1.1  pho  * Copyright (c) 2024 The NetBSD Foundation, Inc.
      5  1.1  pho  * All rights reserved.
      6  1.1  pho  *
      7  1.1  pho  * Redistribution and use in source and binary forms, with or without
      8  1.1  pho  * modification, are permitted provided that the following conditions
      9  1.1  pho  * are met:
     10  1.1  pho  * 1. Redistributions of source code must retain the above copyright
     11  1.1  pho  *    notice, this list of conditions and the following disclaimer.
     12  1.1  pho  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  pho  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  pho  *    documentation and/or other materials provided with the distribution.
     15  1.1  pho  *
     16  1.1  pho  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17  1.1  pho  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18  1.1  pho  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  1.1  pho  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20  1.1  pho  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  1.1  pho  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  1.1  pho  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23  1.1  pho  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24  1.1  pho  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  1.1  pho  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  1.1  pho  * POSSIBILITY OF SUCH DAMAGE.
     27  1.1  pho  */
     28  1.1  pho 
     29  1.1  pho #include <atf-c.h>
     30  1.1  pho 
     31  1.1  pho #if defined(HAVE_STACK_POINTER_H)
     32  1.1  pho #  include <signal.h>
     33  1.1  pho #  include <string.h>
     34  1.1  pho #  include <sys/stdint.h>
     35  1.1  pho #  include <sys/time.h>
     36  1.1  pho #  include "stack_pointer.h"
     37  1.1  pho 
     38  1.1  pho static volatile void* stack_pointer = NULL;
     39  1.1  pho static void on_alarm(int sig __attribute__((__unused__)))
     40  1.1  pho {
     41  1.1  pho 	/*
     42  1.1  pho 	 * Store the stack pointer into a variable so that we can test if
     43  1.1  pho 	 * it's aligned.
     44  1.1  pho 	 */
     45  1.1  pho 	LOAD_SP(stack_pointer);
     46  1.1  pho 
     47  1.1  pho 	/*
     48  1.1  pho 	 * Now we are going to return from a signal
     49  1.1  pho 	 * handler. __sigtramp_siginfo_2 will call setcontext(2) with a
     50  1.1  pho 	 * ucontext provided by the kernel. When that fails it will call
     51  1.1  pho 	 * _Exit(2) with the errno, and the test will fail.
     52  1.1  pho 	 */
     53  1.1  pho }
     54  1.1  pho #endif
     55  1.1  pho 
     56  1.1  pho ATF_TC(misaligned_sp_and_signal);
     57  1.1  pho ATF_TC_HEAD(misaligned_sp_and_signal, tc)
     58  1.1  pho {
     59  1.1  pho 	atf_tc_set_md_var(tc, "descr", "process can return from a signal"
     60  1.1  pho 	    " handler even if the stack pointer is misaligned when a signal"
     61  1.1  pho 	    " arrives");
     62  1.1  pho }
     63  1.1  pho ATF_TC_BODY(misaligned_sp_and_signal, tc)
     64  1.1  pho {
     65  1.1  pho #if defined(HAVE_STACK_POINTER_H)
     66  1.1  pho 	/*
     67  1.1  pho 	 * Set up a handler for SIGALRM.
     68  1.1  pho 	 */
     69  1.1  pho 	struct sigaction sa;
     70  1.1  pho 	memset(&sa, 0, sizeof(sa));
     71  1.1  pho 	sa.sa_handler = &on_alarm;
     72  1.1  pho 	ATF_REQUIRE(sigaction(SIGALRM, &sa, NULL) == 0);
     73  1.1  pho 
     74  1.1  pho 	/*
     75  1.1  pho 	 * Set up an interval timer so that we receive SIGALRM after 50 ms.
     76  1.1  pho 	 */
     77  1.1  pho 	struct itimerval itv;
     78  1.1  pho 	memset(&itv, 0, sizeof(itv));
     79  1.1  pho 	itv.it_value.tv_usec = 1000 * 50;
     80  1.1  pho 	ATF_REQUIRE(setitimer(ITIMER_MONOTONIC, &itv, NULL) == 0);
     81  1.1  pho 
     82  1.1  pho 	/*
     83  1.1  pho 	 * Now misalign the SP. Wait for the signal to arrive and see what
     84  1.1  pho 	 * happens. This should be fine as long as we don't use it to
     85  1.1  pho 	 * access memory.
     86  1.1  pho 	 */
     87  1.1  pho 	MISALIGN_SP;
     88  1.1  pho 	while (stack_pointer == NULL) {
     89  1.1  pho 		/*
     90  1.1  pho 		 * Make sure the compiler does not optimize this busy loop
     91  1.1  pho 		 * away.
     92  1.1  pho 		 */
     93  1.1  pho 		__asm__("" : : : "memory");
     94  1.1  pho 	}
     95  1.1  pho 	/*
     96  1.1  pho 	 * We could successfully return from a signal handler. Now we
     97  1.1  pho 	 * should fix the SP before calling any functions.
     98  1.1  pho 	 */
     99  1.1  pho 	FIX_SP;
    100  1.1  pho 
    101  1.1  pho 	/*
    102  1.1  pho 	 * But was the stack pointer aligned when we were on the signal
    103  1.1  pho 	 * handler?
    104  1.1  pho 	 */
    105  1.1  pho 	ATF_CHECK_MSG(is_sp_aligned((uintptr_t)stack_pointer),
    106  1.1  pho 	    "signal handler was called with a misaligned sp: %p",
    107  1.1  pho 	    stack_pointer);
    108  1.1  pho #else
    109  1.1  pho 	atf_tc_skip("Not implemented for this platform");
    110  1.1  pho #endif
    111  1.1  pho }
    112  1.1  pho 
    113  1.1  pho ATF_TP_ADD_TCS(tp)
    114  1.1  pho {
    115  1.1  pho 	ATF_TP_ADD_TC(tp, misaligned_sp_and_signal);
    116  1.1  pho 	return atf_no_error();
    117  1.1  pho }
    118