kern: Avoid arithmetic overflow in gettimeleft.
Sprinkle assertions in to verify we're monotonically counting the time left down to zero. Reported-by: syzbot+5f6a6329d139810dfe3c@syzkaller.appspotmail.com
This commit is contained in:
parent
9515e06261
commit
eaf33ef422
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: subr_time.c,v 1.34 2022/06/26 22:31:47 riastradh Exp $ */
|
/* $NetBSD: subr_time.c,v 1.35 2022/06/28 02:04:51 riastradh Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1982, 1986, 1989, 1993
|
* Copyright (c) 1982, 1986, 1989, 1993
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: subr_time.c,v 1.34 2022/06/26 22:31:47 riastradh Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: subr_time.c,v 1.35 2022/06/28 02:04:51 riastradh Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
|
@ -207,6 +207,7 @@ inittimeleft(struct timespec *ts, struct timespec *sleepts)
|
||||||
if (itimespecfix(ts)) {
|
if (itimespecfix(ts)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
KASSERT(ts->tv_sec >= 0);
|
||||||
getnanouptime(sleepts);
|
getnanouptime(sleepts);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -214,15 +215,23 @@ inittimeleft(struct timespec *ts, struct timespec *sleepts)
|
||||||
int
|
int
|
||||||
gettimeleft(struct timespec *ts, struct timespec *sleepts)
|
gettimeleft(struct timespec *ts, struct timespec *sleepts)
|
||||||
{
|
{
|
||||||
struct timespec sleptts;
|
struct timespec now, sleptts;
|
||||||
|
|
||||||
|
KASSERT(ts->tv_sec >= 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reduce ts by elapsed time based on monotonic time scale.
|
* Reduce ts by elapsed time based on monotonic time scale.
|
||||||
*/
|
*/
|
||||||
getnanouptime(&sleptts);
|
getnanouptime(&now);
|
||||||
timespecadd(ts, sleepts, ts);
|
KASSERT(timespeccmp(sleepts, &now, <=));
|
||||||
|
timespecsub(&now, sleepts, &sleptts);
|
||||||
|
*sleepts = now;
|
||||||
|
|
||||||
|
if (timespeccmp(ts, &sleptts, <=)) { /* timed out */
|
||||||
|
timespecclear(ts);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
timespecsub(ts, &sleptts, ts);
|
timespecsub(ts, &sleptts, ts);
|
||||||
*sleepts = sleptts;
|
|
||||||
|
|
||||||
return tstohz(ts);
|
return tstohz(ts);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue