On Fri, Jul 03, 2020 at 10:52:15AM +0200, Otto Moerbeek wrote:
> On Thu, Jul 02, 2020 at 08:27:58PM -0500, Scott Cheloha wrote:
> 
> > Hi,
> > 
> > When we recompute the scaling factor during tc_windup() there is an
> > opportunity for arithmetic overflow/underflow when we add the NTP
> > adjustment into the scale:
> > 
> >    649          scale = (u_int64_t)1 << 63;
> >    650          scale += \
> >    651              ((th->th_adjustment + th->th_counter->tc_freq_adj) / 
> > 1024) * 2199;
> >    652          scale /= th->th_counter->tc_frequency;
> >    653          th->th_scale = scale * 2;
> > 
> > At lines 650 and 651, you will overflow/underflow if
> > th->th_counter->tc_freq_adj is sufficiently positive/negative.
> > 
> > I don't like the idea of checking for that overflow during
> > tc_windup().  We can pick a reasonable adjustment range and check for
> > it during adjfreq(2) and that should be good enough.
> > 
> > My strawman proposal is a range of -500000000 to 500000000 parts per
> > billion.  We could push the limits a bit, but half a billion seems
> > like a nice round number to me.
> > 
> > On a perfect clock, this means you can effect a 0.5x slowdown or a
> > 1.5x speedup via adjfreq(2), but no slower/faster.
> > 
> > I don't *think* ntpd(8) would ever reach such extreme adjustments
> > through its algorithm.  I don't think this will break anyone's working
> > setup.
> > 
> > (Maybe I'm wrong, though.  otto@?)
> 
> Right, ntpd is pretty conversative and won't do big adjustments.

So, what is the right way to describe these limits?

"Parts per billion"?  Something else?

Index: lib/libc/sys/adjfreq.2
===================================================================
RCS file: /cvs/src/lib/libc/sys/adjfreq.2,v
retrieving revision 1.7
diff -u -p -r1.7 adjfreq.2
--- lib/libc/sys/adjfreq.2      10 Sep 2015 17:55:21 -0000      1.7
+++ lib/libc/sys/adjfreq.2      6 Jul 2020 21:39:37 -0000
@@ -60,6 +60,10 @@ The
 .Fa freq
 argument is non-null and the process's effective user ID is not that
 of the superuser.
+.It Bq Er EINVAL
+.Fa freq
+is less than -500000000 parts-per-billion or greater than 500000000
+parts-per-billion.
 .El
 .Sh SEE ALSO
 .Xr date 1 ,
Index: sys/kern/kern_time.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_time.c,v
retrieving revision 1.131
diff -u -p -r1.131 kern_time.c
--- sys/kern/kern_time.c        22 Jun 2020 18:25:57 -0000      1.131
+++ sys/kern/kern_time.c        6 Jul 2020 21:39:38 -0000
@@ -391,6 +391,9 @@ sys_settimeofday(struct proc *p, void *v
        return (0);
 }
 
+#define ADJFREQ_MAX (500000000LL << 32)
+#define ADJFREQ_MIN (-500000000LL << 32)
+
 int
 sys_adjfreq(struct proc *p, void *v, register_t *retval)
 {
@@ -408,6 +411,8 @@ sys_adjfreq(struct proc *p, void *v, reg
                        return (error);
                if ((error = copyin(freq, &f, sizeof(f))))
                        return (error);
+               if (f < ADJFREQ_MIN || f > ADJFREQ_MAX)
+                       return (EINVAL);
        }
 
        rw_enter(&tc_lock, (freq == NULL) ? RW_READ : RW_WRITE);

Reply via email to