powerpc/183040: Nested signal handling is broken

Julio Merino julio at meroh.net
Thu Oct 17 00:00:01 UTC 2013


>Number:         183040
>Category:       powerpc
>Synopsis:       Nested signal handling is broken
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-ppc
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Oct 17 00:00:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     Julio Merino
>Release:        FreeBSD 11.0-CURRENT powerpc
>Organization:
>Environment:
System: FreeBSD mastodon.meroh.net 11.0-CURRENT FreeBSD 11.0-CURRENT #9 r256450M: Mon Oct 14 16:35:08 EDT 2013 jmmv at mastodon.meroh.net:/usr/obj/usr/src/sys/GENERIC64 powerpc

Also affects FreeBSD 10.0 alphas.

	
>Description:
	When programming a given signal twice in a nested manner, the
	unprogramming of the top-most signal handler does not properly
	restore the previous (non-default handler).  In other words:

	program signal X
	  program signal X
	    deliver signal X to self -- custom handler runs
	  unprogram signal X
	  deliver signal X to self -- default handler runs or not delivered
	unprogram signal X

	Interestingly, things seem to work well for X = SIGTERM but not
	for X = SIGHUP nor X = SIGINT.  I have not tested other signals.

	I have encountered this bug while running the kyua test suite
	on a powerpc64 machine (specifics detailed above) and noticing
	a couple of tests fail, which work well in other operating
	systems and in amd64.  The test case below is derived form the
	code in kyua.

	Here is the output of the test program on an amd64 machine,
	which to my knowledge is working properly:

SIGNAL 1
Programming at level 1
Programming at level 0
Signal 1 caught correctly
Unprogramming at level 0
Signal 1 caught correctly
Unprogramming at level 1

SIGNAL 2
Programming at level 1
Programming at level 0
Signal 2 caught correctly
Unprogramming at level 0
Signal 2 caught correctly
Unprogramming at level 1

SIGNAL 15
Programming at level 1
Programming at level 0
Signal 15 caught correctly
Unprogramming at level 0
Signal 15 caught correctly
Unprogramming at level 1

	The same test program yields this on powerpc64:

SIGNAL 1
Programming at level 1
Programming at level 0
Signal 1 caught correctly
Unprogramming at level 0
a.out: Signal 1 not caught

>How-To-Repeat:
	Build and run this test program:

-----
#include <err.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

static bool caught = false;

static void
handler(const int signo)
{
    caught = true;
}

static void
do_it(const int signo, const int level)
{
    struct sigaction sa, old_sa;

    printf("Programming at level %d\n", level);

    sa.sa_handler = handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;

    if (sigaction(signo, &sa, &old_sa) == -1)
        err(EXIT_FAILURE, "sigaction program failed");

    if (level > 0)
        do_it(signo, level - 1);

    caught = false;
    kill(getpid(), signo);
    if (caught)
        printf("Signal %d caught correctly\n", signo);
    else
        errx(EXIT_FAILURE, "Signal %d not caught\n", signo);

    if (sigaction(signo, &old_sa, NULL) == -1)
        err(EXIT_FAILURE, "sigaction unprogram failed");

    printf("Unprogramming at level %d\n", level);
}

static void
try_one_signal(const int signo, const int level)
{
    printf("SIGNAL %d\n", signo);
    do_it(signo, level);
    printf("\n");
}

int
main(void)
{
    try_one_signal(SIGHUP, 1);
    try_one_signal(SIGINT, 1);
    try_one_signal(SIGTERM, 1);
    return EXIT_SUCCESS;
}
-----
>Fix:

	


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-ppc mailing list