mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 05:48:05 +00:00
Revert "crtools: close all desriptors only for the root task"
We have a race. Consider we have 3 tasks, A, B and C. A and B share fdtable, C -- does not. Then we might be in a situation when A is restoring memory reading mem images, and B -- forking the C child. In that case descriptors held by A (for mem restore) will be inherited by C and will not get closed. This reverts commit d36e07aabe073993d8ae9695e33f6e45b2eb6a21.
This commit is contained in:
parent
4bd119ddf6
commit
e8ac085af8
21
cr-restore.c
21
cr-restore.c
@ -1213,24 +1213,15 @@ static int restore_task_with_children(void *_arg)
|
||||
current->pid.real, current->pid.virt);
|
||||
}
|
||||
|
||||
if ( !(ca->clone_flags & CLONE_FILES))
|
||||
close_safe(&ca->fd);
|
||||
|
||||
if (current->state != TASK_HELPER) {
|
||||
ret = clone_service_fd(current->rst->service_fd_id);
|
||||
if (ret)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!(ca->clone_flags & CLONE_FILES)) {
|
||||
close_safe(&ca->fd);
|
||||
|
||||
if (current->parent && current->parent->rst->fdt)
|
||||
/*
|
||||
* We're the first child with our own fdtable of
|
||||
* a parent which had it shared. From that parent
|
||||
* we have extra service file descriptors left.
|
||||
*/
|
||||
close_old_servie_fd(current->parent->rst->fdt->nr);
|
||||
}
|
||||
|
||||
pid = getpid();
|
||||
if (current->pid.virt != pid) {
|
||||
pr_err("Pid %d do not match expected %d\n", pid, current->pid.virt);
|
||||
@ -1286,6 +1277,12 @@ static int restore_task_with_children(void *_arg)
|
||||
if (prepare_mappings(pid))
|
||||
exit(1);
|
||||
|
||||
if (!(ca->clone_flags & CLONE_FILES)) {
|
||||
ret = close_old_fds(current);
|
||||
if (ret)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (create_children_and_session())
|
||||
exit(1);
|
||||
|
||||
|
@ -26,7 +26,6 @@ extern int get_service_fd(enum sfd_type type);
|
||||
extern int reserve_service_fd(enum sfd_type type);
|
||||
extern int install_service_fd(enum sfd_type type, int fd);
|
||||
extern int close_service_fd(enum sfd_type type);
|
||||
extern void close_old_servie_fd(int nr);
|
||||
extern bool is_service_fd(int fd, enum sfd_type type);
|
||||
extern bool is_any_service_fd(int fd);
|
||||
|
||||
|
12
util.c
12
util.c
@ -341,18 +341,6 @@ int close_service_fd(enum sfd_type type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Close all unused service descriptors on a depth of nr. */
|
||||
void close_old_servie_fd(int nr)
|
||||
{
|
||||
int level, i;
|
||||
BUG_ON(service_fd_id != 0);
|
||||
for (level = 1; level < nr; level++) {
|
||||
for (i = SERVICE_FD_MIN + 1; i < SERVICE_FD_MAX; i++) {
|
||||
close(__get_service_fd(i, level));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int clone_service_fd(int id)
|
||||
{
|
||||
int ret = -1, i;
|
||||
|
Loading…
x
Reference in New Issue
Block a user