From c6ac396aa3818e47aa82f6c36bea076f64d51c24 Mon Sep 17 00:00:00 2001 From: Pavel Tikhomirov Date: Thu, 11 May 2023 22:59:28 +0800 Subject: [PATCH] timers: improve and fix posix timer id sequence checks This is a patch proposed by Thomas here: https://lore.kernel.org/all/87ilczc7d9.ffs@tglx/ It removes (created id > desired id) "sanity" check and adds proper checking that ids start at zero and increment by one each time when we create/delete a posix timer. First purpose of it is to fix infinite looping in create_posix_timers on old pre 3.11 kernels. Second purpose is to allow kernel interface of creating posix timers with desired id change from iterating with predictable next id to just setting next id directly. And at the same time removing predictable next id so that criu with this patch would not get to infinite loop in create_posix_timers if this happens. Thanks a lot to Thomas! Suggested-by: Thomas Gleixner Signed-off-by: Pavel Tikhomirov --- criu/pie/restorer.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c index 9873fdc11..1f08bc2a0 100644 --- a/criu/pie/restorer.c +++ b/criu/pie/restorer.c @@ -1169,7 +1169,7 @@ static int timerfd_arm(struct task_restore_args *args) static int create_posix_timers(struct task_restore_args *args) { int ret, i; - kernel_timer_t next_id; + kernel_timer_t next_id = 0, timer_id; struct sigevent sev; for (i = 0; i < args->posix_timers_n; i++) { @@ -1183,25 +1183,26 @@ static int create_posix_timers(struct task_restore_args *args) sev.sigev_value.sival_ptr = args->posix_timers[i].spt.sival_ptr; while (1) { - ret = sys_timer_create(args->posix_timers[i].spt.clock_id, &sev, &next_id); + ret = sys_timer_create(args->posix_timers[i].spt.clock_id, &sev, &timer_id); if (ret < 0) { pr_err("Can't create posix timer - %d\n", i); return ret; } - if (next_id == args->posix_timers[i].spt.it_id) - break; - - ret = sys_timer_delete(next_id); - if (ret < 0) { - pr_err("Can't remove temporaty posix timer 0x%x\n", next_id); - return ret; - } - - if ((long)next_id > args->posix_timers[i].spt.it_id) { + if (timer_id != next_id) { pr_err("Can't create timers, kernel don't give them consequently\n"); return -1; } + next_id++; + + if (timer_id == args->posix_timers[i].spt.it_id) + break; + + ret = sys_timer_delete(timer_id); + if (ret < 0) { + pr_err("Can't remove temporaty posix timer 0x%x\n", timer_id); + return ret; + } } }