Bug 31468 - sigisemptyset returns true when the set contains signals larger than 34
Summary: sigisemptyset returns true when the set contains signals larger than 34
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: 2.40
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-03-10 09:20 UTC by Miao Wang
Modified: 2024-03-12 09:03 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Miao Wang 2024-03-10 09:20:14 UTC
Hi,

I found that there might be a bug in `sigisemptyset`. The following code reproduces this issue:

```c
#define _GNU_SOURCE
#include<signal.h>
#include<stdio.h>
#include<stdlib.h>

int main(){
        sigset_t set;
        int rc = sigemptyset(&set);
        if (rc < 0){
                perror("sigemptyset");
                exit(1);
        }
        printf("NSIG=%d\n", NSIG);
        rc = sigaddset(&set, 34);
        if (rc < 0){
                perror("sigaddset");
                exit(1);
        }
        printf("isemptyset: %d\n", sigisemptyset(&set));
        printf("ismember(34): %d\n", sigismember(&set, 34));

        return 0;
}
```

`sigisemptyset` returns 1 even when the signal number 34 is in the set. 

The bug may be related to the following code:

https://elixir.bootlin.com/glibc/glibc-2.39/source/sysdeps/unix/sysv/linux/sigsetops.h#L69

where the variable `ret` is declared as `int` rather than `unsigned long int`, which is used in `struct __sigset_t`. On 64bit platforms where `long` is 64 bits and `int` is 32 bits, the above code leaves the higher 32 bits of each `__val` member unchecked.

I wonder if this is intended or a bug.
Comment 1 Andreas Schwab 2024-03-10 10:48:18 UTC
This is broken since the beginning of time.
Comment 2 Andreas Schwab 2024-03-12 09:03:14 UTC
Fixed by commit 2173173d57.