CRaC / criu

Other
28 stars 10 forks source link

Fix inheriting standard descriptors #13

Open rvansa opened 10 months ago

rvansa commented 10 months ago

The snprintf-fix addresses invalid merge with crac 3.14; the code was comparing recorded FDs to be inherited with uninitalized on-stack memory.

Using reopen_fd_as_nocheck needs a bit more insight to validate; maybe a proper fix would be elsewhere. When stdout (FD 1) is redirected to a file, this code receives new_fd set to FD 3 and fails as fle->fe->fd == 1 is open FD.

rvansa commented 10 months ago

Looks like this gets stuck in IgnoredFileDescriptorsTest; CRIU gets stuck in

#0  syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
#1  0x0000564ab912cc6b in sys_futex (addr2=0x0, val3=0, timeout=0x7fff7f70e840, val1=<optimized out>, op=0, addr1=0x7f8f8e9750b0) at include/common/lock.h:28
#2  wait_fds_event () at criu/files.c:225
#3  0x0000564ab912ebab in open_fdinfos (me=0x7f8f8e975058) at criu/files.c:1243
#4  prepare_fds (me=0x7f8f8e975058) at criu/files.c:1334
#5  0x0000564ab911e717 in restore_one_alive_task (core=0x564aba6aeec0, pid=2638870) at criu/cr-restore.c:905
#6  restore_one_task (core=0x564aba6aeec0, pid=2638870) at criu/cr-restore.c:1256
#7  restore_task_with_children (_arg=<optimized out>) at criu/cr-restore.c:1976
#8  0x0000564ab910eb92 in clone3_with_pid_noasan (fn=fn@entry=0x564ab911dcd0 <restore_task_with_children>, arg=arg@entry=0x7fff7f70eaa0, flags=0, exit_signal=exit_signal@entry=17, pid=<optimized out>)
    at criu/clone-noasan.c:82
#9  0x0000564ab911a580 in fork_with_pid (item=item@entry=0x7f8f8e975058) at criu/cr-restore.c:1465
#10 0x0000564ab911b3d3 in restore_root_task (init=0x7f8f8e975058) at criu/cr-restore.c:2338
#11 0x0000564ab911ca90 in cr_restore_tasks () at criu/cr-restore.c:2705
#12 0x0000564ab90f35f1 in main (argc=<optimized out>, argv=0x7fff7f70ed78, envp=<optimized out>) at criu/crtools.c:315
rvansa commented 9 months ago

The IgnoredFileDescriptorsTest checkpointed a process with FD 43 mapped to stdout. CRIU selected FD 1 to create the pipe going to the new stdout, but then it was not created but rather inherited, and FD 43 waited indefinitely for that. With the current solution the process won't be stuck, CRIU will create a new pipe for FD 43 (haven't found the other end, though) but it won't go to new stdout, as we ask specifically for inheriting FDs 0..2. Therefore if the user is in such a weird situation where he would actually want to use FD 43 (note that he must have already marked this FD to be ignored by JVM!) he would also have to use CRAC_CRIU_OPTS="--inherit-fd 'fd[43]:fd[1]'" to inherit new stdout as well.

Anyway, the issue was resolved and this can be reviewed/integrated.