[LTP] [PATCH V2] syscalls: clock_settime: Add test around y2038 vulnerability
Viresh Kumar
viresh.kumar@linaro.org
Thu May 28 11:11:48 CEST 2020
On 28-05-20, 10:27, Arnd Bergmann wrote:
> On Thu, May 28, 2020 at 8:57 AM Viresh Kumar <viresh.kumar@linaro.org> wrote:
> >
> > This adds a test around the y2038 vulnerability, it sets the system time
> > to just before y2038 time (i.e. max value that can be stored in s32),
> > and adds a timer to expire just after crossing it.
> >
> > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> > ---
> > V2:
> > - Fix the y2038 bug in the test itself, changes in the setup() routine.
> > :)
>
> So I assume this version works as expected?
> I don't see any more problems with it.
Absolutely perfectly. I don't know what the problem with timer was
earlier, maybe it was related to a different way I was trying to
capture the signal with (i.e. SAFE_SIGNAL(SIGALRM, sighandler)).
But this (and the earlier patch as well, perhaps I tested even an
earlier version then) works just fine.
> > + ret = tv->clock_settime(CLOCK_REALTIME, tst_ts_get(&ts));
> > + if (ret == -1)
> > + tst_brk(TBROK | TERRNO, "clock_settime() failed");
But I noticed that even this version may not be good enough, as I am
still doing the same thing in setup(), i.e. setting time to just
before y2038 to test if it is y2038 safe or not. I believe even that
isn't fine ?
> > +
> > + tst_its_set_time(&its, time + EXPIREDELTA, 0, 0, 0);
> > +
> > + TEST(tv->timer_settime(timer, TIMER_ABSTIME, tst_its_get(&its), NULL));
> > + if (TST_RET == -1)
> > + tst_brk(TBROK | TTERRNO, "timer_settime() failed");
> > +
> > + if (sigwait(&set, &sig) == -1)
> > + tst_brk(TBROK, "sigwait() failed");
>
> Should you maybe check the time after the expiration to ensure the
> timer ran for the expected length?
>
> I suppose you can read the time in CLOCK_MONOTONIC to check
> for the elapsed time regardless of what the kernel might think the
> CLOCK_REALTIME is after this.
This should be enough I believe.
diff --git a/testcases/kernel/syscalls/clock_settime/clock_settime03.c b/testcases/kernel/syscalls/clock_settime/clock_settime03.c
index 9e316378b1cc..876651a5d537 100644
--- a/testcases/kernel/syscalls/clock_settime/clock_settime03.c
+++ b/testcases/kernel/syscalls/clock_settime/clock_settime03.c
@@ -13,7 +13,7 @@
#define EXPIREDELTA 3
-static struct tst_ts ts;
+static struct tst_ts ts, end;
static struct tst_its its;
static struct test_variants {
@@ -37,7 +37,6 @@ static void setup(void)
{
struct test_variants *tv = &variants[tst_variant];
unsigned long long time = 0x7FFFFFFF; /* Time just before y2038 */
- struct tst_ts end;
int ret;
tst_res(TINFO, "Testing variant: %s", tv->desc);
@@ -72,6 +71,7 @@ static void run(void)
.sigev_notify = SIGEV_SIGNAL,
.sigev_signo = SIGABRT,
};
+ struct tst_ts diff;
timer_t timer;
sigset_t set;
int sig, ret;
@@ -105,7 +105,16 @@ static void run(void)
if (sigwait(&set, &sig) == -1)
tst_brk(TBROK, "sigwait() failed");
+ ret = tv->clock_gettime(CLOCK_REALTIME, tst_ts_get(&end));
+ if (ret == -1)
+ tst_brk(TBROK | TERRNO, "clock_gettime() failed");
+
if (sig == SIGABRT) {
+ diff = tst_ts_diff(end, ts);
+
+ if (tst_ts_get_sec(diff) != EXPIREDELTA)
+ tst_res(TINFO, "Test slept longer than it should have, expected:%d, actual:%lld",
+ EXPIREDELTA, tst_ts_get_sec(diff));
tst_res(TPASS, "clock_settime(): Y2038 test passed");
return;
}
--
viresh
More information about the ltp
mailing list