From haug@hawaii.conterra.com Mon Mar 15 20:58:12 1999
Return-Path: <haug@hawaii.conterra.com>
Received: from hawaii.conterra.com (hawaii.conterra.com [209.12.164.32])
	by hub.freebsd.org (Postfix) with ESMTP id 9063A1507C
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 15 Mar 1999 20:57:30 -0800 (PST)
	(envelope-from haug@hawaii.conterra.com)
Received: (from haug@localhost)
	by hawaii.conterra.com (8.8.8/8.8.7) id XAA05229;
	Mon, 15 Mar 1999 23:57:10 -0500 (EST)
Message-Id: <199903160457.XAA05229@hawaii.conterra.com>
Date: Mon, 15 Mar 1999 23:57:10 -0500 (EST)
From: Brian Haug <haug@hawaii.conterra.com>
Reply-To: haug@hawaii.conterra.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: adjtime bug (tv_sec >2147 ) and enhancement (nil first arg)
X-Send-Pr-Version: 3.2

>Number:         10609
>Category:       kern
>Synopsis:       adjtime bug (tv_sec > 2147) and enhancement (nil first arg)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    ceri
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Mar 15 21:00:00 PST 1999
>Closed-Date:    Sun Jun 08 11:00:38 PDT 2003
>Last-Modified:  Sun Jun 08 11:00:38 PDT 2003
>Originator:     Brian Haug
>Release:        FreeBSD 3.1-RELEASE i386 (?? send-pr from different system)
>Organization:
None
>Environment:

	probably any system with adjtime system call


>Description:

	1. Bug: adjtime can not handle adjustments whos absolute value exceeds
		2148 (or stricly exceeds 2147)
	2. Change request: adjtime does not accept a nil first argument to
		allow the application to determine the current delta being
		applied to the clock.
	3. Documentation doesn't note the first issue (code fix attached).

>How-To-Repeat:

	use "date -a 2148" (code in follow on report) or examine the code.
	Note that 2147 seconds (expressed as microseconds) is real close
	to MAXINT, and 2148 seconds would exceed this.


	Call adjtime with the value NULL for the first argument, note that
	the system call will fail.

>Fix:
	

Hopefully the code diffs are all correct.  I've used BRH_ to diferentiate the
two fixes, and would actually suggest not using the ifdefs.  The two problems
are somewhat intertwined, so I appologize for tying them together.  The man
page only attempts to dealwith the NIL first argument issue since the other
problem is now fixed in the kernel.

*** /usr/src/sys/kern/kern_time.c.old	Sun Oct 25 10:44:51 1998
--- /usr/src/sys/kern/kern_time.c	Sun Mar 14 08:02:31 1999
***************
*** 322,328 ****
--- 322,332 ----
  }
  
  int	tickdelta;			/* current clock skew, us. per tick */
+ #ifdef BRH_ADJTIME_BIG
+ long long	timedelta;		/* unapplied time correction, us. */
+ #else
  long	timedelta;			/* unapplied time correction, us. */
+ #endif
  static long	bigadj = 1000000;	/* use 10x skew above bigadj us. */
  
  #ifndef _SYS_SYSPROTO_H_
***************
*** 338,351 ****
--- 342,370 ----
  	register struct adjtime_args *uap;
  {
  	struct timeval atv;
+ #ifdef BRH_ADJTIME_BIG
+ 	long long ndelta, odelta;
+ 	register long ntickdelta;
+ #else
  	register long ndelta, ntickdelta, odelta;
+ #endif
  	int s, error;
+ #ifdef BRH_ADJTIME_NULL
+ 	int for_real;
+ #endif
  
  	if ((error = suser(p->p_ucred, &p->p_acflag)))
  		return (error);
+ #ifndef BRH_ADJTIME_NULL
  	if ((error =
  	    copyin((caddr_t)uap->delta, (caddr_t)&atv, sizeof(struct timeval))))
  		return (error);
+ #else
+ 	for_real = (caddr_t)NULL != (caddr_t)uap->delta;
+ 	if (for_real && (error =
+ 	    copyin((caddr_t)uap->delta, (caddr_t)&atv, sizeof(struct timeval))))
+ 		return (error);
+ #endif
  
  	/*
  	 * Compute the total correction and the rate at which to apply it.
***************
*** 354,360 ****
--- 373,386 ----
  	 * hardclock(), tickdelta will become zero, lest the correction
  	 * overshoot and start taking us away from the desired final time.
  	 */
+ #ifdef BRH_ADJTIME_NULL
+ 	if (for_real) {
+ #endif
+ #ifdef BRH_ADJTIME_BIG
+ 	ndelta = (long long)atv.tv_sec * 1000000 + atv.tv_usec;
+ #else
  	ndelta = atv.tv_sec * 1000000 + atv.tv_usec;
+ #endif
  	if (ndelta > bigadj || ndelta < -bigadj)
  		ntickdelta = 10 * tickadj;
  	else
***************
*** 369,378 ****
--- 395,413 ----
  	 */
  	if (ndelta < 0)
  		ntickdelta = -ntickdelta;
+ #ifdef BRH_ADJTIME_NULL
+ 	}
+ #endif
  	s = splclock();
  	odelta = timedelta;
+ #ifdef BRH_ADJTIME_NULL
+ 	if (for_real) {
+ #endif
  	timedelta = ndelta;
  	tickdelta = ntickdelta;
+ #ifdef BRH_ADJTIME_NULL
+ 	}
+ #endif
  	splx(s);
  
  	if (uap->olddelta) {
*** /usr/src/sys/sys/kernel.h.old	Sun Mar 14 07:56:11 1999
--- /usr/src/sys/sys/kernel.h	Sun Mar 14 07:57:04 1999
***************
*** 73,79 ****
--- 73,83 ----
  extern int ticks;
  extern int lbolt;			/* once a second sleep address */
  extern int tickdelta;
+ #ifdef BRH_ADJTIME_BIG
+ extern long long timedelta;
+ #else
  extern long timedelta;
+ #endif
  
  #endif /* KERNEL */
  
*** /usr/src/lib/libc/sys/adjtime.2.old	Sun Mar 14 08:08:37 1999
--- /usr/src/lib/libc/sys/adjtime.2	Sun Mar 14 08:14:13 1999
***************
*** 66,71 ****
--- 66,76 ----
  .Fn adjtime
  is called again.
  If
+ .Fa delta
+ is nil, then no changes are made to the clock.
+ This is useful when one wants to determine the amount of adjustment which
+ is yet to be performed.
+ If
  .Fa olddelta
  is non-nil,
  the structure pointed to will contain, upon return, the

>Release-Note:
>Audit-Trail:

From: Poul-Henning Kamp <phk@critter.freebsd.dk>
To: haug@hawaii.conterra.com
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: kern/10609: adjtime bug (tv_sec >2147 ) and enhancement (nil first arg) 
Date: Wed, 24 Mar 1999 16:16:13 +0100

 I don't really know if I think it makes sense to extend the area of
 adjtime(2)'s validity.
 
 If you were to tweak your clock 2148 seconds, it would take you 7160
 minutes (at the 300msec/min fast rate).  That is 5 days.
 
 Depending on you xtal, your clock may have drifted up to:
 
 	500PPM * 7160 * 60 = 214.8 seconds
 
 in the same amount of time, so we're talking about potentialy getting 
 it 10% wrong...
 
 In comparison the ntp_adjtime() interface only allows you to tweak
 the phase +/- half a second.
 
 I really fail to see an application where it makes sense.  If you are
 synchronizing via modem to ACTS or similar, you would be better off
 using NTPDv4 for that since it will try to discipline your xtals
 frequency error.
 
 Summary: I would rather return E2BIG if people try to do that, but
 I'm not religious about it.
 
 --
 Poul-Henning Kamp             FreeBSD coreteam member
 phk@FreeBSD.ORG               "Real hackers run -current on their laptop."
 FreeBSD -- It will take a long time before progress goes too far!
 
State-Changed-From-To: open->feedback 
State-Changed-By: iedowse 
State-Changed-When: Sun Jan 20 09:16:42 PST 2002 
State-Changed-Why:  

What was the conclusion here? Would a modification that range-checks 
or caps the delta be acceptable? 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=10609 
State-Changed-From-To: feedback->closed 
State-Changed-By: ceri 
State-Changed-When: Sun Jun 8 11:00:36 PDT 2003 
State-Changed-Why:  
Feedback timeout (6 months or more). 
I will handle any feedback that this closure generates. 


Responsible-Changed-From-To: freebsd-bugs->ceri 
Responsible-Changed-By: ceri 
Responsible-Changed-When: Sun Jun 8 11:00:36 PDT 2003 
Responsible-Changed-Why:  
Feedback timeout (6 months or more). 
I will handle any feedback that this closure generates. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=10609 
>Unformatted:
