diff options
author | cheloha <cheloha@cvs.openbsd.org> | 2020-07-15 21:20:09 +0000 |
---|---|---|
committer | cheloha <cheloha@cvs.openbsd.org> | 2020-07-15 21:20:09 +0000 |
commit | 0df106c4dcbfa326b3ccb8225c296832cb5fd94e (patch) | |
tree | 1f5948a60b177ef4a8a1aaaecb8aa1a5425fc46a /sys/kern | |
parent | 6e4605ec4931a8c61e26e5ac8f8e8161ba21e72c (diff) |
settimeofday(2): securelevel 2: prevent root from freezing the UTC clock
At securelevel 2 we prevent root from rewinding the kernel UTC clock.
The rationale given in the comment is that this prevents a compromised
root from setting arbitrary timestamps on files.
I can't really speak to the efficacy of this mitigation, or to the
efficacy of the securelevel concept in general, but the implementation
of this mitigation is wrong. We need to check:
timespeccmp(ts, &now, <=)
instead of
timespeccmp(ts, &now, <)
like we do now.
Time is a continuous value that is always advancing. We must prevent
root from setting the kernel UTC clock to its current value in
addition to prior values. Setting the UTC clock to its current value
amounts to rewinding it even if we cannot actually measure the
difference with a timespec.
With this change, at securelevel 2, root can no longer completely
freeze the UTC clock.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_time.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 872480aa314..d5d02b0c670 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_time.c,v 1.132 2020/07/09 02:17:07 cheloha Exp $ */ +/* $OpenBSD: kern_time.c,v 1.133 2020/07/15 21:20:08 cheloha Exp $ */ /* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */ /* @@ -91,7 +91,7 @@ settime(const struct timespec *ts) * setting arbitrary time stamps on files. */ nanotime(&now); - if (securelevel > 1 && timespeccmp(ts, &now, <)) { + if (securelevel > 1 && timespeccmp(ts, &now, <=)) { printf("denied attempt to set clock back %lld seconds\n", (long long)now.tv_sec - ts->tv_sec); return (EPERM); |