Bug 7950

Summary: POSIX.1/SUS conformance bug: sigprocmask() incorrectly mods sig-mask
Product: [Retired] Red Hat Linux Reporter: Jay Turner <jturner>
Component: kernelAssignee: Michael K. Johnson <johnsonm>
Status: CLOSED CURRENTRELEASE QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: 6.0CC: srevivo
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2000-01-04 22:20:40 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
Proposed patch for sigprocmask(2) defect none

Description Glen Foster 1999-12-22 18:06:10 UTC
PCTS tests for sigprocmask() have uncovered a defect in the way signal
masks are managed.  The test-case below specifically provides an "invalid"
*how* argument and expects the resulting signal mask to NOT change.  But
upon execution of the code below, the signal mask *is* modified.

Cristian Gafton has analyzed this and concurs about it being a kernel bug.

[snip]
#include <stdio.h>
#include <signal.h>
#include <errno.h>

#define INVALID_HOW (SIG_SETMASK + SIG_BLOCK + SIG_UNBLOCK)

main()
{
        int pid, x;
        sigset_t set, oset;
        void dumpset();

printf("**** Start *****\n");
        sigemptyset(&set);
        sigemptyset(&oset);
        dumpset(set, " set");
        dumpset(oset, "oset");

        printf("\nCalling sigprocmask(SIG_SETMASK, &set, &oset)\n");
        x = sigprocmask(SIG_SETMASK, &set, &oset);
        printf("sigprocmask(SIG_SETMASK) returns %d, errno %d\n", x,
		errno);
        if (errno) perror("sigprocmask");
	dumpset(set, " set");
        dumpset(oset, "oset");

printf("\t... adding SIGHUP to signal set\n");
        sigaddset(&set, SIGHUP);
        dumpset(set, " set");

        printf("\nCalling sigprocmask(INVALID_HOW, &set, &oset)\n");
        x = sigprocmask(INVALID_HOW, &set, &oset);
        printf("sigprocmask returns %d, errno %d\n", x, errno);
        if (errno) perror("sigprocmask");
        dumpset(set, " set");
        dumpset(oset, "oset");

        sigprocmask(SIG_SETMASK, (sigset_t *)0, &oset);
        if (sigismember(&oset, SIGHUP))
                printf("\n\t\tOOPS: signal mask altered!\n\n");
        exit(0);
}
char *n;
{
        int i = 0, *ip = (int *) &s;

        printf("%s = ", n);
        while (i < sizeof(s) / sizeof(int)) {
                /*printf("[0x%08x]", *ip++);*/
                printf("%1d", *ip++);
                if (++i % 105 == 0)
                        printf("\n");
        }
        printf("\n");
        return;
}
void
dumpset(s, n)
sigset_t s;
     dumpset(set, " set");

Comment 1 Glen Foster 1999-12-22 18:45:59 UTC
Created attachment 42 [details]
Proposed patch for sigprocmask(2) defect

Comment 2 Cristian Gafton 2000-01-04 22:20:59 UTC
Assigned to dledford

Comment 3 Alan Cox 2000-08-08 18:03:22 UTC
This should be ok since 2.2.14 kernels (6.2)