NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

port-sparc/59323: t_sigaction:sigaction_resethand test is failing



>Number:         59323
>Category:       port-sparc
>Synopsis:       t_sigaction:sigaction_resethand test is failing
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-sparc-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Apr 19 01:30:01 +0000 2025
>Originator:     Taylor R Campbell
>Release:        current, 10, 9, ...
>Organization:
The ResetBSparcD Sigaction
>Environment:
>Description:
FAILED: Child process did not exit cleanly; it either failed to process the signal or SA_RESETHAND is broken; raw exit status was 139

Specifically, as soon as the SIGUSR1 signal is delivered here on return from kill(2), the process gets a SIGSEGV immediately afterward, with pc set to 0 according to gdb:

     64     kill(getpid(), SIGUSR1);

https://nxr.netbsd.org/xref/src/tests/lib/libc/sys/t_sigaction.c?r=1.5#64

Turns out the problem is that SA_RESETHAND has been broken in sparc since the newlock2 merge in 2007 -- it always tries to invoke address 0 as the signal handler, because it _first_ resets the sigaction and _then_ reads the sigaction address to invoke.  Oops.

    543 	sendsig_reset(l, sig);
...
    576 		catcher = (u_int)SIGACTION(p, sig).sa_handler;
    577 		tf->tf_pc = catcher;
    578 		tf->tf_npc = catcher + 4;
    579 		tf->tf_out[0] = sig;
    580 		tf->tf_out[1] = (int)&fp->sf_si;
    581 		tf->tf_out[2] = (int)&fp->sf_uc;
    582 		tf->tf_out[6] = newsp;
    583 		tf->tf_out[7] = (int)ps->sa_sigdesc[sig].sd_tramp - 8;

https://nxr.netbsd.org/xref/src/sys/arch/sparc/sparc/machdep.c?r=1.341#543
>How-To-Repeat:
cd /usr/tests/lib/libc/sys
atf-run t_sigaction | atf-report
>Fix:
read SIGACTION(p, sig).sa_handler _before_ calling sendsig_reset



Home | Main Index | Thread Index | Old Index