From 2940109a244eaab5d892cdcfb5baeef206987c86 Mon Sep 17 00:00:00 2001 From: Pavel Tikhomirov Date: Thu, 27 Jun 2013 23:32:24 +0400 Subject: [PATCH] posix-timer: Restore and fix one timer This also add function to check if time represented by two numbers is valid. I.e. for timespec(sec, nsec), sec and nsec must be > 0 and nsec must be less when NSEC_PER_SEC. Signed-off-by: Pavel Tikhomirov Signed-off-by: Pavel Emelyanov --- cr-restore.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/cr-restore.c b/cr-restore.c index f5b131a20..98af24681 100644 --- a/cr-restore.c +++ b/cr-restore.c @@ -1498,6 +1498,47 @@ out: return ret; } +static inline int timespec_valid(struct timespec *ts) +{ + return (ts->tv_sec >= 0) && ((unsigned long)ts->tv_nsec < NSEC_PER_SEC); +} + +static inline int posix_timer_restore_and_fix(PosixTimerEntry *pte, + struct restore_posix_timer *pt) +{ + pt->val.it_interval.tv_sec = pte->isec; + pt->val.it_interval.tv_nsec = pte->insec; + + if (!timespec_valid(&pt->val.it_interval)) { + pr_err("Invalid timer interval(posix)\n"); + return -1; + } + + if (pte->vsec == 0 && pte->vnsec == 0) { + // Remaining time was too short. Set it to + // interval to make the timer armed and work. + pt->val.it_value.tv_sec = pte->isec; + pt->val.it_value.tv_nsec = pte->insec; + } else { + pt->val.it_value.tv_sec = pte->vsec; + pt->val.it_value.tv_nsec = pte->vnsec; + } + + if (!timespec_valid(&pt->val.it_value)) { + pr_err("Invalid timer value(posix)\n"); + return -1; + } + + pt->spt.it_id = pte->it_id; + pt->spt.clock_id = pte->clock_id; + pt->spt.si_signo = pte->si_signo; + pt->spt.it_sigev_notify = pte->it_sigev_notify; + pt->spt.sival_ptr = decode_pointer(pte->sival_ptr); + pt->overrun = pte->overrun; + + return 0; +} + static inline int verify_cap_size(CredsEntry *ce) { return ((ce->n_cap_inh == CR_CAP_SIZE) && (ce->n_cap_eff == CR_CAP_SIZE) &&