Verify that tv_sec value specified in settimeofday() and clock_settime()

(CLOCK_REALTIME case) system calls is non negative.
This commit hides a kernel panic in atrtc_settime() as the clock_ts_to_ct()
does not properly convert negative tv_sec.

ps. in my opinion clock_ts_to_ct() should be rewritten to properly handle
negative tv_sec values.

Differential Revision:	https://reviews.freebsd.org/D4714
Reviewed by:		kib

MFC after:	1 week
This commit is contained in:
Dmitry Chagin 2015-12-27 15:37:07 +00:00
parent ff64a90ed9
commit 3e18d701de
3 changed files with 12 additions and 4 deletions

View File

@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd December 20, 2015
.Dd December 27, 2015
.Dt CLOCK_GETTIME 2
.Os
.Sh NAME
@ -134,6 +134,8 @@ The following error codes may be set in
.It Bq Er EINVAL
The
.Fa clock_id
or
.Fa timespec
argument
was not a valid value.
.It Bq Er EPERM

View File

@ -28,7 +28,7 @@
.\" @(#)gettimeofday.2 8.2 (Berkeley) 5/26/95
.\" $FreeBSD$
.\"
.Dd December 20, 2015
.Dd December 27, 2015
.Dt GETTIMEOFDAY 2
.Os
.Sh NAME
@ -110,6 +110,10 @@ system call even when the system is secure.
The following error codes may be set in
.Va errno :
.Bl -tag -width Er
.It Bq Er EINVAL
The supplied
.Fa timeval
value is invalid.
.It Bq Er EPERM
A user other than the super-user attempted to set the time.
.El

View File

@ -398,7 +398,8 @@ kern_clock_settime(struct thread *td, clockid_t clock_id, struct timespec *ats)
return (error);
if (clock_id != CLOCK_REALTIME)
return (EINVAL);
if (ats->tv_nsec < 0 || ats->tv_nsec >= 1000000000)
if (ats->tv_nsec < 0 || ats->tv_nsec >= 1000000000 ||
ats->tv_sec < 0)
return (EINVAL);
/* XXX Don't convert nsec->usec and back */
TIMESPEC_TO_TIMEVAL(&atv, ats);
@ -618,7 +619,8 @@ kern_settimeofday(struct thread *td, struct timeval *tv, struct timezone *tzp)
return (error);
/* Verify all parameters before changing time. */
if (tv) {
if (tv->tv_usec < 0 || tv->tv_usec >= 1000000)
if (tv->tv_usec < 0 || tv->tv_usec >= 1000000 ||
tv->tv_sec < 0)
return (EINVAL);
error = settime(td, tv);
}