summaryrefslogtreecommitdiff
path: root/sys/kern/kern_time.c
diff options
context:
space:
mode:
authorThomas Nordin <nordin@cvs.openbsd.org>2002-07-25 22:18:28 +0000
committerThomas Nordin <nordin@cvs.openbsd.org>2002-07-25 22:18:28 +0000
commitd9bfc760e5f8614b88c80d2d82c1b408e25bfba2 (patch)
tree5102c9dc619a41f977498078f3c9c2afb8079c1b /sys/kern/kern_time.c
parent35f479f1c8c53ca3d8d1694d020433a09a70909a (diff)
Avoid time wrap at securelevel 2. ok millert@ fgsch@
Diffstat (limited to 'sys/kern/kern_time.c')
-rw-r--r--sys/kern/kern_time.c83
1 files changed, 39 insertions, 44 deletions
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 0574220b3fd..165587ffc7c 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_time.c,v 1.30 2002/06/11 06:07:45 nordin Exp $ */
+/* $OpenBSD: kern_time.c,v 1.31 2002/07/25 22:18:27 nordin Exp $ */
/* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */
/*
@@ -55,7 +55,7 @@
#include <machine/cpu.h>
-void settime(struct timeval *);
+int settime(struct timeval *);
void itimerround(struct timeval *);
/*
@@ -69,13 +69,41 @@ void itimerround(struct timeval *);
*/
/* This function is used by clock_settime and settimeofday */
-void
-settime(tv)
- struct timeval *tv;
+int
+settime(struct timeval *tv)
{
struct timeval delta;
int s;
+ /*
+ * Don't allow the time to be set forward so far it will wrap
+ * and become negative, thus allowing an attacker to bypass
+ * the next check below. The cutoff is 1 year before rollover
+ * occurs, so even if the attacker uses adjtime(2) to move
+ * the time past the cutoff, it will take a very long time
+ * to get to the wrap point.
+ *
+ * XXX: we check against INT_MAX since on 64-bit
+ * platforms, sizeof(int) != sizeof(long) and
+ * time_t is 32 bits even when atv.tv_sec is 64 bits.
+ */
+ if (tv->tv_sec > INT_MAX - 365*24*60*60) {
+ printf("denied attempt to set clock forward to %ld\n",
+ tv->tv_sec);
+ return (EPERM);
+ }
+ /*
+ * 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.
+ */
+ if (securelevel > 1 && timercmp(tv, &time, <)) {
+ printf("denied attempt to set clock back %ld seconds\n",
+ time.tv_sec - tv->tv_sec);
+ return (EPERM);
+ }
+
/* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
s = splclock();
timersub(tv, &time, &delta);
@@ -84,6 +112,8 @@ settime(tv)
timeradd(&runtime, &delta, &runtime);
splx(s);
resettodr();
+
+ return (0);
}
/* ARGSUSED */
@@ -139,17 +169,9 @@ sys_clock_settime(p, v, retval)
TIMESPEC_TO_TIMEVAL(&atv,&ats);
- /*
- * 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.
- */
- if (securelevel > 1 && timercmp(&atv, &time, <))
- return (EPERM);
- settime(&atv);
+ error = settime(&atv);
- return (0);
+ return (error);
}
int
@@ -298,35 +320,8 @@ sys_settimeofday(p, v, retval)
(void *)&atz, sizeof(atz))))
return (error);
if (SCARG(uap, tv)) {
- /*
- * Don't allow the time to be set forward so far it will wrap
- * and become negative, thus allowing an attacker to bypass
- * the next check below. The cutoff is 1 year before rollover
- * occurs, so even if the attacker uses adjtime(2) to move
- * the time past the cutoff, it will take a very long time
- * to get to the wrap point.
- *
- * XXX: we check against INT_MAX since on 64-bit
- * platforms, sizeof(int) != sizeof(long) and
- * time_t is 32 bits even when atv.tv_sec is 64 bits.
- */
- if (atv.tv_sec > INT_MAX - 365*24*60*60) {
- printf("denied attempt to set clock forward to %ld\n",
- atv.tv_sec);
- return (EPERM);
- }
- /*
- * 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.
- */
- if (securelevel > 1 && timercmp(&atv, &time, <)) {
- printf("denied attempt to set clock back %ld seconds\n",
- time.tv_sec - atv.tv_sec);
- return (EPERM);
- }
- settime(&atv);
+ if ((error = settime(&atv)) != 0)
+ return (error);
}
if (SCARG(uap, tzp))
tz = atz;