Module Name: src Committed By: elad Date: Sat Oct 3 20:48:42 UTC 2009
Modified Files: src/sys/kern: kern_time.c src/sys/secmodel/keylock: secmodel_keylock.c src/sys/secmodel/securelevel: secmodel_securelevel.c src/sys/sys: timevar.h Log Message: Introduce time_wraps() to check if setting the time will wrap it (or close to it). Useful for secmodels. Replace open-coded form with it in secmodel code (securelevel, keylock). Note: I need to find a way to make secmodel_keylock.c ~<100 lines. To generate a diff of this commit: cvs rdiff -u -r1.161 -r1.162 src/sys/kern/kern_time.c cvs rdiff -u -r1.2 -r1.3 src/sys/secmodel/keylock/secmodel_keylock.c cvs rdiff -u -r1.15 -r1.16 \ src/sys/secmodel/securelevel/secmodel_securelevel.c cvs rdiff -u -r1.25 -r1.26 src/sys/sys/timevar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_time.c diff -u src/sys/kern/kern_time.c:1.161 src/sys/kern/kern_time.c:1.162 --- src/sys/kern/kern_time.c:1.161 Sun Sep 13 18:45:11 2009 +++ src/sys/kern/kern_time.c Sat Oct 3 20:48:42 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_time.c,v 1.161 2009/09/13 18:45:11 pooka Exp $ */ +/* $NetBSD: kern_time.c,v 1.162 2009/10/03 20:48:42 elad Exp $ */ /*- * Copyright (c) 2000, 2004, 2005, 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.161 2009/09/13 18:45:11 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.162 2009/10/03 20:48:42 elad Exp $"); #include <sys/param.h> #include <sys/resourcevar.h> @@ -1461,3 +1461,29 @@ mutex_spin_exit(&timer_lock); mutex_exit(proc_lock); } + +/* + * Check if the time will wrap if set to ts. + * + * ts - timespec describing the new time + * delta - the delta between the current time and ts + */ +bool +time_wraps(struct timespec *ts, struct timespec *delta) +{ + + /* + * 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. + */ + if ((ts->tv_sec > LLONG_MAX - 365*24*60*60) || + (delta->tv_sec < 0 || delta->tv_nsec < 0)) + return true; + + return false; +} Index: src/sys/secmodel/keylock/secmodel_keylock.c diff -u src/sys/secmodel/keylock/secmodel_keylock.c:1.2 src/sys/secmodel/keylock/secmodel_keylock.c:1.3 --- src/sys/secmodel/keylock/secmodel_keylock.c:1.2 Sat Aug 15 09:43:59 2009 +++ src/sys/secmodel/keylock/secmodel_keylock.c Sat Oct 3 20:48:42 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: secmodel_keylock.c,v 1.2 2009/08/15 09:43:59 mbalmer Exp $ */ +/* $NetBSD: secmodel_keylock.c,v 1.3 2009/10/03 20:48:42 elad Exp $ */ /*- * Copyright (c) 2009 Marc Balmer <m...@msys.ch> * Copyright (c) 2006 Elad Efrat <e...@netbsd.org> @@ -54,7 +54,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: secmodel_keylock.c,v 1.2 2009/08/15 09:43:59 mbalmer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: secmodel_keylock.c,v 1.3 2009/10/03 20:48:42 elad Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -64,6 +64,7 @@ #include <sys/mount.h> #include <sys/sysctl.h> #include <sys/vnode.h> +#include <sys/timevar.h> #include <dev/keylock.h> @@ -176,18 +177,7 @@ struct timespec *ts = arg1; struct timespec *delta = arg2; - /* - * 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. - */ - if (keylock_position() > 1 && - ((ts->tv_sec > LLONG_MAX - 365*24*60*60) || - (delta->tv_sec < 0 || delta->tv_nsec < 0))) + if (keylock_position() > 1 && time_wraps(ts, delta)) result = KAUTH_RESULT_DENY; break; } Index: src/sys/secmodel/securelevel/secmodel_securelevel.c diff -u src/sys/secmodel/securelevel/secmodel_securelevel.c:1.15 src/sys/secmodel/securelevel/secmodel_securelevel.c:1.16 --- src/sys/secmodel/securelevel/secmodel_securelevel.c:1.15 Fri Oct 2 20:15:07 2009 +++ src/sys/secmodel/securelevel/secmodel_securelevel.c Sat Oct 3 20:48:42 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: secmodel_securelevel.c,v 1.15 2009/10/02 20:15:07 elad Exp $ */ +/* $NetBSD: secmodel_securelevel.c,v 1.16 2009/10/03 20:48:42 elad Exp $ */ /*- * Copyright (c) 2006 Elad Efrat <e...@netbsd.org> * All rights reserved. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: secmodel_securelevel.c,v 1.15 2009/10/02 20:15:07 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: secmodel_securelevel.c,v 1.16 2009/10/03 20:48:42 elad Exp $"); #ifdef _KERNEL_OPT #include "opt_insecure.h" @@ -50,6 +50,7 @@ #include <sys/sysctl.h> #include <sys/vnode.h> #include <sys/module.h> +#include <sys/timevar.h> #include <miscfs/specfs/specdev.h> @@ -242,19 +243,9 @@ struct timespec *ts = arg1; struct timespec *delta = arg2; - /* - * 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. - */ - if (securelevel > 1 && - ((ts->tv_sec > LLONG_MAX - 365*24*60*60) || - (delta->tv_sec < 0 || delta->tv_nsec < 0))) + if (securelevel > 1 && time_wraps(ts, delta)) result = KAUTH_RESULT_DENY; + break; } Index: src/sys/sys/timevar.h diff -u src/sys/sys/timevar.h:1.25 src/sys/sys/timevar.h:1.26 --- src/sys/sys/timevar.h:1.25 Sun Mar 29 19:21:20 2009 +++ src/sys/sys/timevar.h Sat Oct 3 20:48:42 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: timevar.h,v 1.25 2009/03/29 19:21:20 christos Exp $ */ +/* $NetBSD: timevar.h,v 1.26 2009/10/03 20:48:42 elad Exp $ */ /* * Copyright (c) 2005, 2008 The NetBSD Foundation. @@ -178,6 +178,7 @@ void timerupcall(struct lwp *); void time_init(void); void time_init2(void); +bool time_wraps(struct timespec *, struct timespec *); extern time_t time_second; /* current second in the epoch */ extern time_t time_uptime; /* system uptime in seconds */