2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-30 22:05:36 +00:00

tty: skip ioctl(TIOCSLCKTRMIOS) if possible

If ioctl(TIOCSLCKTRMIOS) fails with EPERM it means that a CRIU
process lacks of CAP_SYS_ADMIN capability. But we can use
ioctl(TIOCGLCKTRMIOS) to *read* current ->termios_locked
value from the kernel and if it's the same as we already have
we can skip failing ioctl(TIOCSLCKTRMIOS) safely.

Adrian has recently posted [1] a very good patch to allow ioctl(TIOCSLCKTRMIOS)
for processes that have CAP_CHECKPOINT_RESTORE (right now it requires CAP_SYS_ADMIN).

[1] https://lore.kernel.org/all/20231206134340.7093-1-areber@redhat.com/

Suggested-by: Andrei Vagin <avagin@gmail.com>
Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
This commit is contained in:
Alexander Mikhalitsyn
2023-12-08 17:36:32 +01:00
committed by Andrei Vagin
parent 8a51639e3d
commit f86f1b8491

View File

@@ -817,8 +817,26 @@ static int do_restore_tty_parms(void *arg, int fd, pid_t pid)
* on termios too. Just to be on the safe side. * on termios too. Just to be on the safe side.
*/ */
if ((p->has & HAS_TERMIOS_L) && ioctl(fd, TIOCSLCKTRMIOS, &p->tl) < 0) if ((p->has & HAS_TERMIOS_L) && ioctl(fd, TIOCSLCKTRMIOS, &p->tl) < 0) {
goto err; struct termios t;
if (errno != EPERM)
goto err;
memzero(&t, sizeof(t));
if (ioctl(fd, TIOCGLCKTRMIOS, &t) < 0) {
pr_perror("Can't get tty locked params on %#x", p->tty_id);
goto err;
}
/*
* The ioctl(TIOCSLCKTRMIOS) requires a CRIU process to be privileged
* in the init_user_ns, but if the current "termios_locked" value equal
* to the "termios_locked" value from the image, we can safely skip setting it.
*/
if (memcmp(&t, &p->tl, sizeof(struct termios)) != 0)
goto err;
}
if ((p->has & HAS_TERMIOS) && ioctl(fd, TCSETS, &p->t) < 0) if ((p->has & HAS_TERMIOS) && ioctl(fd, TCSETS, &p->t) < 0)
goto err; goto err;