fork() succeeds with a descriptor missing when its pin cannot be allocated
Los mantenedores suelen responder en 2 días
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 75/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- c
- Área
- operating-systems
Línea de trabajo
Empieza en src/runtime/fork-state.c en fork_ipc_send_fd_table() para ver cómo maneja el retorno NULL de fd_lifetime_pin_locked(). Luego revisa src/syscall/fdtable.c para fd_lifetime_pin_spare() para entender los casos de fallo de asignación. El fix debe hacer que fork() devuelva -1 con ENOMEM cuando no se puede asignar un pin, y puedes verificarlo usando la reproducción por inyección de fallos descrita.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
fork_ipc_send_fd_table() (src/runtime/fork-state.c) skips a slot when fd_lifetime_pin_locked() returns NULL:
pin = fd_lifetime_pin_locked(i);
if (!pin)
continue;
fd_lifetime_pin_spare() returns NULL for a closed slot, for a slot with no host descriptor, and when malloc fails. The loop has already skipped FD_CLOSED under the same fd_lock hold, so on an open slot with a host descriptor NULL means the allocation failed. The slot is then left out of the table sent to the child, the send completes, and the parent's fork() returns the child pid. Nothing is logged.
Linux fork() either gives the child every descriptor or fails with ENOMEM.
Reproduction
The allocation cannot be made to fail from the guest, so this uses fault injection on b57f367. In fd_lifetime_pin_spare() (src/syscall/fdtable.c):
- lifetime = malloc(sizeof(*lifetime));
+ lifetime = (fd == 5 && getenv("PINFAIL"))
+ ? NULL
+ : malloc(sizeof(*lifetime));
Guest:
for (int i = 0; i < 5; i++)
open("/dev/null", O_RDONLY); /* fds 3..7 */
pid_t pid = fork();
printf("[%s] fork returned %d\n", pid ? "parent" : "child", (int) pid);
if (pid == 0) {
for (int fd = 3; fd <= 7; fd++)
printf("child fd %d: %s\n", fd,
fcntl(fd, F_GETFD) >= 0 ? "open" : strerror(errno));
_exit(0);
}
waitpid(pid, NULL, 0);
With PINFAIL=1:
[parent] fork returned 2
[child] fork returned 0
child fd 3: open
child fd 4: open
child fd 5: Bad file descriptor
child fd 6: open
child fd 7: open
Without the variable, fd 5 is open in the child.
Expected
fork() returns -1 with ENOMEM and no child is left running.
The skip is older than the pin. At 628181b, where this loop still calls dup(), a guest holding 1021 descriptors under ulimit -n 1280 gets a successful fork() and a child with descriptors missing.
- Lenguaje dominante
- C
- Estrellas
- 271
- Forks
- 28
- Merge medio
- 2 d 18 h
- PR fusionados (30 d)
- 19
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de sysprog21/elfuse
-
bug
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
Los mantenedores suelen responder en 2 días
-
bug
Dificultad 4/5 3-5 días Aptitud para principiantes 52/100
Los mantenedores suelen responder en 2 días
-
bug
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
Los mantenedores suelen responder en 2 días
-
Dificultad 3/5 1-2 días Aptitud para principiantes 78/100
Los mantenedores suelen responder en 2 días
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 48/100
Los mantenedores suelen responder en 2 días
Todos los issues de sysprog21/elfuse
Issues similares
-
Discover carries headerEdges that nothing reads since #1914 moved E0507/E0517 to the compiler graphAbiertotech-debt
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
Los mantenedores suelen responder en 1 día
-
2个显示的问题Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
coolsnowwolf/lede#14209 ·
-
Cannot run pico-hsm-tool.pyAbierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 75/100
polhenarejos/pico-hsm#147 ·
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
OpenPrinting/cups#1746 ·
Los mantenedores suelen responder en 1 día
-
Status: Opened
Dificultad 1/5 Menos de una hora Aptitud para principiantes 75/100
Los mantenedores suelen responder en 1 día