diff options
author | bde <bde@FreeBSD.org> | 1998-02-25 04:10:32 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1998-02-25 04:10:32 +0000 |
commit | 689816601019aa721c95320df5096cd8d8a9ee18 (patch) | |
tree | 0d4259f1ec5b03068568a968e02982c50a75afb6 /sys/kern/kern_time.c | |
parent | 014146c040ed6640e606b46e58c066fc3a1c442c (diff) | |
download | FreeBSD-src-689816601019aa721c95320df5096cd8d8a9ee18.zip FreeBSD-src-689816601019aa721c95320df5096cd8d8a9ee18.tar.gz |
Fixed the calculation of `delta' in settime(). We once set all
times consistently wrong (up to 1 tick too late), but recent changes
fixed the setting of the main clock, making other times inconsistent.
The inconsistencies tended to show up as a negative resource usage
for the process that set the time.
Fixed the check for setting the clock backwards. A stale timestamp
(`time') was checked, so it was possible to set the clock backwards
by up to almost 1 tick. Until recently, this bug was compensated
for by setting the clock consistently wrong.
Merged the comment about setting the clock backwards from Lite2.
Removed latency micro-optimizations/speed pessimizations in settime().
microtime() and set_timecounter() are relatively expensive, and
they must be called together with clock updates blocked to get a
consistent `delta', so significant latency optimizations are not
possible.
Removed some stale comments.
Diffstat (limited to 'sys/kern/kern_time.c')
-rw-r--r-- | sys/kern/kern_time.c | 43 |
1 files changed, 14 insertions, 29 deletions
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index fb78ffc..295e8fa 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)kern_time.c 8.1 (Berkeley) 6/10/93 - * $Id: kern_time.c,v 1.40 1997/11/07 08:52:58 phk Exp $ + * $Id: kern_time.c,v 1.41 1998/02/20 16:35:53 phk Exp $ */ #include <sys/param.h> @@ -77,43 +77,32 @@ static int settime(tv) struct timeval *tv; { - struct timeval delta; + struct timeval delta, tv1; struct timespec ts; struct proc *p; int s; - /* - * Must not set clock backwards in highly secure mode. - */ s = splclock(); - delta.tv_sec = tv->tv_sec - time.tv_sec; - delta.tv_usec = tv->tv_usec - time.tv_usec; - splx(s); + microtime(&tv1); + delta.tv_sec = tv->tv_sec - tv1.tv_sec; + delta.tv_usec = tv->tv_usec - tv1.tv_usec; timevalfix(&delta); - if (delta.tv_sec < 0 && securelevel > 1) - return (EPERM); - s = splclock(); /* - * Recalculate delta directly to minimize clock interrupt - * latency. Fix it after the ipl has been lowered. + * If the system is secure, we do not allow the time to be + * set to an earlier value (it may be slowed using adjtime, + * but not set back). This feature prevent interlopers from + * setting arbitrary time stamps on files. */ - delta.tv_sec = tv->tv_sec - time.tv_sec; - delta.tv_usec = tv->tv_usec - time.tv_usec; + if (delta.tv_sec < 0 && securelevel > 1) { + splx(s); + return (EPERM); + } + ts.tv_sec = tv->tv_sec; ts.tv_nsec = tv->tv_usec * 1000; set_timecounter(&ts); - /* - * XXX should arrange for microtime() to agree with *tv if - * it is called now. As it is, it may add up to about - * `tick' unwanted usec. - * Another problem is that clock interrupts may occur at - * other than multiples of `tick'. It's not worth fixing - * this here, since the problem is also caused by tick - * adjustments. - */ (void) splsoftclock(); - timevalfix(&delta); timevaladd(&boottime, &delta); timevaladd(&runtime, &delta); for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) { @@ -239,10 +228,6 @@ nanosleep1(p, rqt, rmt) atv.tv_usec = 0; } } - /* - * XXX this is not as careful as settimeofday() about minimising - * interrupt latency. The hzto() interface is inconvenient as usual. - */ s = splclock(); timevaladd(&atv, &time); timo = hzto(&atv); |