Skip to content

Commit

Permalink
tty: skip ioctl(TIOCSLCKTRMIOS) if possible
Browse files Browse the repository at this point in the history
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/[email protected]/

Suggested-by: Andrei Vagin <[email protected]>
Signed-off-by: Alexander Mikhalitsyn <[email protected]>
  • Loading branch information
mihalicyn authored and avagin committed Dec 11, 2023
1 parent 378da3b commit dc49eb4
Showing 1 changed file with 20 additions and 2 deletions.
22 changes: 20 additions & 2 deletions criu/tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit dc49eb4

Please sign in to comment.