mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 06:15:24 +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:
committed by
Andrei Vagin
parent
8a51639e3d
commit
f86f1b8491
22
criu/tty.c
22
criu/tty.c
@@ -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.
|
||||
*/
|
||||
|
||||
if ((p->has & HAS_TERMIOS_L) && ioctl(fd, TIOCSLCKTRMIOS, &p->tl) < 0)
|
||||
goto err;
|
||||
if ((p->has & HAS_TERMIOS_L) && ioctl(fd, TIOCSLCKTRMIOS, &p->tl) < 0) {
|
||||
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)
|
||||
goto err;
|
||||
|
Reference in New Issue
Block a user