~ubuntu-branches/debian/squeeze/ntp/squeeze-201010051545

« back to all changes in this revision

Viewing changes to libntp/adjtime.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2009-01-05 21:10:03 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20090105211003-mh6zc3um4k1uhsj7
Tags: 1:4.2.4p4+dfsg-8
It did not properly check the return value of EVP_VerifyFinal
which results in an malformed DSA signature being treated as
a good signature rather than as an error.  (CVE-2009-0021)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#ifdef HAVE_CONFIG_H
2
 
# include <config.h>
3
 
#endif
4
 
 
5
 
#ifdef MPE 
6
 
/*
7
 
 * MPE lacks adjtime(), so we define our own.  But note that time slewing has
8
 
 * a sub-second accuracy bug documented in SR 5003462838 which prevents ntpd
9
 
 * from being able to maintain clock synch.  Because of the bug, this adjtime()
10
 
 * implementation as used by ntpd has a side-effect of screwing up the hardware
11
 
 * PDC clock, which will need to be reset with a reboot.
12
 
 *
13
 
 * This problem affects all versions of MPE at the time of this writing (when
14
 
 * MPE/iX 7.0 is the most current).  It only causes bad things to happen when
15
 
 * doing continuous clock synchronization with ntpd; note that you CAN run ntpd
16
 
 * with "disable ntp" in ntp.conf if you wish to provide a time server.
17
 
 *
18
 
 * The one-time clock adjustment functionality of ntpdate and ntp_timeset can
19
 
 * be used without screwing up the PDC clock.
20
 
 * 
21
 
 */
22
 
#include <time.h>
23
 
 
24
 
int adjtime(struct timeval *delta, struct timeval *olddelta);
25
 
 
26
 
int adjtime(struct timeval *delta, struct timeval *olddelta)
27
 
 
28
 
{
29
 
/* Documented, supported MPE system intrinsics. */
30
 
 
31
 
extern void GETPRIVMODE(void);
32
 
extern void GETUSERMODE(void);
33
 
 
34
 
/* Undocumented, unsupported MPE internal functions. */
35
 
 
36
 
extern long long current_correction_usecs(void);
37
 
extern long long get_time(void);
38
 
extern void get_time_change_info(long long *, char *, char *);
39
 
extern long long pdc_time(int *);
40
 
extern void set_time_correction(long long, int, int);
41
 
extern long long ticks_to_micro(long long);
42
 
 
43
 
long long big_sec, big_usec, new_correction = 0LL;
44
 
long long prev_correction;
45
 
 
46
 
if (delta != NULL) {
47
 
  /* Adjustment required.  Convert delta to 64-bit microseconds. */
48
 
  big_sec = (long)delta->tv_sec;
49
 
  big_usec = delta->tv_usec;
50
 
  new_correction = (big_sec * 1000000LL) + big_usec;
51
 
}
52
 
 
53
 
GETPRIVMODE();
54
 
 
55
 
/* Determine how much of a previous correction (if any) we're interrupting. */
56
 
prev_correction = current_correction_usecs();
57
 
 
58
 
if (delta != NULL) {
59
 
  /* Adjustment required. */
60
 
 
61
 
#if 0
62
 
  /* Speculative code disabled until bug SR 5003462838 is fixed.  This bug
63
 
     prevents accurate time slewing, and indeed renders ntpd inoperable. */
64
 
 
65
 
  if (prev_correction != 0LL) {
66
 
    /* A previous adjustment did not complete.  Since the PDC UTC clock was
67
 
    immediately jumped at the start of the previous adjustment, we must
68
 
    explicitly reset it to the value of the MPE local time clock minus the
69
 
    time zone offset. */
70
 
 
71
 
    char pwf_since_boot, recover_pwf_time;
72
 
    long long offset_ticks, offset_usecs, pdc_usecs_current, pdc_usecs_wanted;
73
 
    int hpe_status;
74
 
 
75
 
    get_time_change_info(&offset_ticks, &pwf_since_boot, &recover_pwf_time);
76
 
    offset_usecs = ticks_to_micro(offset_ticks);
77
 
    pdc_usecs_wanted = get_time() - offset_usecs;
78
 
    pdc_usecs_current = pdc_time(&hpe_status);
79
 
    if (hpe_status == 0) 
80
 
      /* Force new PDC time by starting an extra correction. */
81
 
      set_time_correction(pdc_usecs_wanted - pdc_usecs_current,0,1);
82
 
  }
83
 
#endif /* 0 */
84
 
    
85
 
  /* Immediately jump the PDC time to the new value, and then initiate a 
86
 
     gradual MPE time correction slew. */
87
 
  set_time_correction(new_correction,0,1);
88
 
}
89
 
 
90
 
GETUSERMODE();
91
 
 
92
 
if (olddelta != NULL) {
93
 
  /* Caller wants to know remaining amount of previous correction. */
94
 
  (long)olddelta->tv_sec = prev_correction / 1000000LL;
95
 
  olddelta->tv_usec = prev_correction % 1000000LL;
96
 
}
97
 
 
98
 
return 0;
99
 
}
100
 
#endif /* MPE */
101
 
 
102
 
#ifdef NEED_HPUX_ADJTIME
103
 
/*************************************************************************/
104
 
/* (c) Copyright Tai Jin, 1988.  All Rights Reserved.                    */
105
 
/*     Hewlett-Packard Laboratories.                                     */
106
 
/*                                                                       */
107
 
/* Permission is hereby granted for unlimited modification, use, and     */
108
 
/* distribution.  This software is made available with no warranty of    */
109
 
/* any kind, express or implied.  This copyright notice must remain      */
110
 
/* intact in all versions of this software.                              */
111
 
/*                                                                       */
112
 
/* The author would appreciate it if any bug fixes and enhancements were */
113
 
/* to be sent back to him for incorporation into future versions of this */
114
 
/* software.  Please send changes to tai@iag.hp.com or ken@sdd.hp.com.   */
115
 
/*************************************************************************/
116
 
 
117
 
/*
118
 
 * Revision history
119
 
 *
120
 
 * 9 Jul 94     David L. Mills, Unibergity of Delabunch
121
 
 *              Implemented variable threshold to limit age of
122
 
 *              corrections; reformatted code for readability.
123
 
 */
124
 
 
125
 
#ifndef lint
126
 
static char RCSid[] = "adjtime.c,v 3.1 1993/07/06 01:04:42 jbj Exp";
127
 
#endif
128
 
 
129
 
#include <sys/types.h>
130
 
#include <sys/ipc.h>
131
 
#include <sys/msg.h>
132
 
#include <time.h>
133
 
#include <signal.h>
134
 
#include "adjtime.h"
135
 
 
136
 
#define abs(x)  ((x) < 0 ? -(x) : (x))
137
 
 
138
 
/*
139
 
 * The following paramters are appropriate for an NTP adjustment
140
 
 * interval of one second.
141
 
 */
142
 
#define ADJ_THRESH 200          /* initial threshold */
143
 
#define ADJ_DELTA 4             /* threshold decrement */
144
 
 
145
 
static long adjthresh;          /* adjustment threshold */
146
 
static long saveup;             /* corrections accumulator */
147
 
 
148
 
/*
149
 
 * clear_adjtime - reset accumulator and threshold variables
150
 
 */
151
 
void
152
 
_clear_adjtime(void)
153
 
{
154
 
        saveup = 0;
155
 
        adjthresh = ADJ_THRESH;
156
 
}
157
 
 
158
 
/*
159
 
 * adjtime - hp-ux copout of the standard Unix adjtime() system call
160
 
 */
161
 
int
162
 
adjtime(
163
 
        register struct timeval *delta,
164
 
        register struct timeval *olddelta
165
 
        )
166
 
{
167
 
        struct timeval newdelta;
168
 
 
169
 
        /*
170
 
         * Corrections greater than one second are done immediately.
171
 
         */
172
 
        if (delta->tv_sec) {
173
 
                adjthresh = ADJ_THRESH;
174
 
                saveup = 0;
175
 
                return(_adjtime(delta, olddelta));
176
 
        }
177
 
 
178
 
        /*
179
 
         * Corrections less than one second are accumulated until
180
 
         * tripping a threshold, which is initially set at ADJ_THESH and
181
 
         * reduced in ADJ_DELTA steps to zero. The idea here is to
182
 
         * introduce large corrections quickly, while making sure that
183
 
         * small corrections are introduced without excessive delay. The
184
 
         * idea comes from the ARPAnet routing update algorithm.
185
 
         */
186
 
        saveup += delta->tv_usec;
187
 
        if (abs(saveup) >= adjthresh) {
188
 
                adjthresh = ADJ_THRESH;
189
 
                newdelta.tv_sec = 0;
190
 
                newdelta.tv_usec = saveup;
191
 
                saveup = 0;
192
 
                return(_adjtime(&newdelta, olddelta));
193
 
        } else {
194
 
                adjthresh -= ADJ_DELTA;
195
 
        }
196
 
 
197
 
        /*
198
 
         * While nobody uses it, return the residual before correction,
199
 
         * as per Unix convention.
200
 
         */
201
 
        if (olddelta)
202
 
            olddelta->tv_sec = olddelta->tv_usec = 0;
203
 
        return(0);
204
 
}
205
 
 
206
 
/*
207
 
 * _adjtime - does the actual work
208
 
 */
209
 
int
210
 
_adjtime(
211
 
        register struct timeval *delta,
212
 
        register struct timeval *olddelta
213
 
        )
214
 
{
215
 
        register int mqid;
216
 
        MsgBuf msg;
217
 
        register MsgBuf *msgp = &msg;
218
 
 
219
 
        /*
220
 
         * Get the key to the adjtime message queue (note that we must
221
 
         * get it every time because the queue might have been removed
222
 
         * and recreated)
223
 
         */
224
 
        if ((mqid = msgget(KEY, 0)) == -1)
225
 
            return (-1);
226
 
        msgp->msgb.mtype = CLIENT;
227
 
        msgp->msgb.tv = *delta;
228
 
        if (olddelta)
229
 
            msgp->msgb.code = DELTA2;
230
 
        else
231
 
            msgp->msgb.code = DELTA1;
232
 
 
233
 
        /*
234
 
         * Tickle adjtimed and snatch residual, if indicated. Lots of
235
 
         * fanatic error checking here.
236
 
         */
237
 
        if (msgsnd(mqid, &msgp->msgp, MSGSIZE, 0) == -1)
238
 
            return (-1);
239
 
        if (olddelta) {
240
 
                if (msgrcv(mqid, &msgp->msgp, MSGSIZE, SERVER, 0) == -1)
241
 
                    return (-1);
242
 
                *olddelta = msgp->msgb.tv;
243
 
        }
244
 
        return (0);
245
 
}
246
 
 
247
 
#else
248
 
# if NEED_QNX_ADJTIME
249
 
/*
250
 
 * Emulate adjtime() using QNX ClockAdjust().
251
 
 * Chris Burghart <burghart@atd.ucar.edu>, 11/2001
252
 
 *
253
 
 * This is a *very* simple implementation of adjtime() for QNX.  
254
 
 * ClockAdjust() is used to tweak the system clock by about +- 1/10 
255
 
 * of its current clock period per tick until the desired delta is 
256
 
 * achieved.
257
 
 */
258
 
# include <math.h>
259
 
# include <stdio.h>
260
 
# include <sys/neutrino.h>
261
 
# include <sys/time.h>
262
 
 
263
 
# include <ntp_stdlib.h>
264
 
 
265
 
int 
266
 
adjtime (struct timeval *delta, struct timeval *olddelta)
267
 
{
268
 
    double delta_nsec;
269
 
    double delta_nsec_old;
270
 
    struct _clockadjust adj;
271
 
    struct _clockadjust oldadj;
272
 
    /*
273
 
     * How many nanoseconds are we adjusting?
274
 
     */
275
 
    delta_nsec = delta->tv_sec * 1e9 + delta->tv_usec * 1000;
276
 
    /*
277
 
     * Build the adjust structure and call ClockAdjust()
278
 
     */
279
 
    if (delta_nsec != 0)
280
 
    {
281
 
        struct _clockperiod period;
282
 
        long count;
283
 
        long increment;
284
 
 
285
 
        /*
286
 
         * Get the current clock period (nanoseconds)
287
 
         */
288
 
        if (ClockPeriod (CLOCK_REALTIME, 0, &period, 0) < 0)
289
 
            return -1;
290
 
 
291
 
        /*
292
 
         * Set the adjust increment to approximately 1/10 timer period per 
293
 
         * clock tick.
294
 
         */
295
 
        count = 1 + (long)(fabs(10 * delta_nsec / period.nsec));
296
 
        increment = (long)(delta_nsec / count);
297
 
 
298
 
        adj.tick_nsec_inc = increment;
299
 
        adj.tick_count = count;
300
 
    }
301
 
    else
302
 
    {
303
 
        adj.tick_nsec_inc = 0;
304
 
        adj.tick_count = 0;
305
 
    }
306
 
 
307
 
    if (ClockAdjust (CLOCK_REALTIME, &adj, &oldadj) < 0)
308
 
        return -1;
309
 
 
310
 
    /*
311
 
     * Build olddelta
312
 
     */
313
 
    delta_nsec_old = oldadj.tick_count * oldadj.tick_nsec_inc;
314
 
    olddelta->tv_sec = (int)(delta_nsec_old / 1e9);
315
 
    olddelta->tv_usec = (int)((delta_nsec_old - 1.0e9 * olddelta->tv_sec) / 
316
 
                              1000);
317
 
            
318
 
    return 0;
319
 
}
320
 
# else /* no special adjtime() needed */
321
 
int adjtime_bs;
322
 
# endif
323
 
#endif