Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 Oct 2004 06:54:12 GMT
From:      Mark Andrews <marka@daemon.lab.isc.org>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   threads/72953: fork() unblocks blocked signals w/o PTHREAD_SCOPE_SYSTEM
Message-ID:  <200410210654.i9L6sCjk029637@daemon.lab.isc.org>
Resent-Message-ID: <200410210700.i9L70i4x004725@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         72953
>Category:       threads
>Synopsis:       fork() unblocks blocked signals w/o PTHREAD_SCOPE_SYSTEM
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-threads
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Oct 21 07:00:44 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Mark Andrews
>Release:        FreeBSD 5.3-BETA6 i386
>Organization:
ISC
>Environment:
System: FreeBSD daemon.lab.isc.org 5.3-BETA6 FreeBSD 5.3-BETA6 #16: Tue Oct 5 23:37:23 UTC 2004 jinmei@daemon.lab.isc.org:/hog0/users/jinmei/src/sys/i386/compile/DAEMON i386


>Description:

	fork() clears blocked signals unless PTHREAD_SCOPE_SYSTEM is set.
	
>How-To-Repeat:

	Run the following program with and without the arguement system.
	In the first case the program will incorrectly be killed by the
	SIGTERM.  In the second case the signal will be blocked and
	sigwait returns.

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>

sigset_t signal_mask;

void
dofork() {
	switch (fork()) {
	case 0:
		break;
	case -1:
		_exit(1);
	default:
		_exit(0);
	}
	fprintf(stderr, "fork\n");
	fflush(stderr);
}

static void *
waiter(void *arg) {
        int result;
        int sig;

        result = sigwait(&signal_mask, &sig);
        if (result != 0)
                fprintf(stderr, "sigwait: %\n", strerror(result));
        else
                fprintf(stderr, "signal %d\n", sig);
	fflush(stderr);
        return (NULL);
}

int
main(int argc, char **argv) {
        pthread_t id;
	pthread_attr_t attr;
        int result;
	int scope = 0;

        if (argc > 1) {
                if (strcmp(argv[1], "system") == 0)
                        scope = 1;
        }

        sigemptyset (&signal_mask);
        sigaddset (&signal_mask, SIGTERM);

        result = pthread_sigmask(SIG_BLOCK, &signal_mask, NULL);
        if (result != 0)
                fprintf(stderr, "pthread_sigmask: %\n", strerror(result));
        else
                fprintf(stderr, "pthread_sigmask: OK\n");
	fflush(stderr);

	dofork();

	result = pthread_attr_init(&attr);
        if (result != 0)
                fprintf(stderr, "pthread_attr_init: %\n", strerror(result));
        else
                fprintf(stderr, "pthread_attr_init: OK\n");
	fflush(stderr);
	
	if (scope) {
		result = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
		if (result != 0)
			fprintf(stderr, "pthread_attr_setscope: %\n",
				strerror(result));
		else
			fprintf(stderr, "pthread_attr_setscope: OK\n");
	} else
		fprintf(stderr, "default scope\n");
	fflush(stderr);

        result = pthread_create (&id, &attr, waiter, NULL);
        if (result != 0)
                fprintf(stderr, "pthread_create: %\n", strerror(result));
        else
                fprintf(stderr, "pthread_create: OK\n");
	fflush(stderr);
        if (kill(getpid(), SIGTERM) == -1)
                perror("kill");
        else
                fprintf(stderr, "kill: OK\n");
	fflush(stderr);
        result = pthread_join(id, NULL);
        if (result != 0)
                fprintf(stderr, "pthread_join: %\n", strerror(result));
        else
                fprintf(stderr, "pthread_join: OK\n");
	fflush(stderr);
        return(0);
}

>Fix:

	


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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200410210654.i9L6sCjk029637>