google / google/gvisor

Deadlock in setsid() with shared signal handlers

Open
#14,275 0 comments 0 reactions 0 assignees View on GitHub
type: bug
Dominant language
Go
Stars
19.3k
Forks
2k
Avg merge
3d 5h
Merged PRs (30d)
264

Description

### Description

We observed a gVisor pod hanging indefinitely. Investigation traced the
root cause to setsid() called with shared signal handlers. The issue can
be reproduced as follows.

### Steps to reproduce

1. Compile the following code.
```
// gcc -O0 -o repro repro.c
#define _GNU_SOURCE
#include
#include
#include
#include
#include

static char child_stack[1 << 20];
static int sync_pipe[2];

static int child_fn(void *arg) {
setpgid(0, 0); // child enters its own process group
char b = 'x';
write(sync_pipe[1], &b, 1);
for (;;) pause();
return 0;
}

int main(void) {
pid_t p = fork(); // make the real caller a non-session-leader
if (p > 0) { waitpid(p, NULL, 0); return 0; }

pipe(sync_pipe);
clone(child_fn, child_stack + sizeof(child_stack),
CLONE_VM | CLONE_SIGHAND | SIGCHLD, NULL); // shares signalHandlers
char b; read(sync_pipe[0], &b, 1);

fprintf(stderr, "calling setsid()\n");
setsid(); // hangs the sentry here
fprintf(stderr, "setsid() returned (no deadlock)\n");
return 0;
}
```
1. execute it inside gvisor and hang indefinitely.
```
runsc --network=host do repro
T(pid=2) calling setsid()
```

### runsc version

```shell
runsc version release-20260817.0-70-g3c5eee17dc45
spec: 1.2.1
```

### docker version (if using docker)

```shell

```

### uname

_No response_

### kubectl (if using Kubernetes)

```shell

```

### repo state (if built from source)

release-20260817.0-70-g3c5eee17d

### runsc debug logs (if available)

```shell

```

Contributor guide

Open the contributing guide

Research direction

Start at gVisor's setsid() syscall handling and the shared signal-handler path, using the supplied fork/clone reproducer to observe where execution stops. Trace the interaction between the session change and shared handlers, then verify that the reproducer returns from setsid() without hanging and add regression coverage if the surrounding syscall tests provide an appropriate entry point.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, go, linux
Domain
operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.