Bug Summary

File:src/usr.sbin/ntpd/ntp.c
Warning:line 564, column 9
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ntp.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/ntpd/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/ntpd -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/ntpd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/ntpd/ntp.c
1/* $OpenBSD: ntp.c,v 1.168 2021/10/24 21:24:19 deraadt Exp $ */
2
3/*
4 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5 * Copyright (c) 2004 Alexander Guy <alexander.guy@andern.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include <sys/types.h>
21#include <sys/time.h>
22#include <sys/stat.h>
23#include <errno(*__errno()).h>
24#include <fcntl.h>
25#include <paths.h>
26#include <poll.h>
27#include <pwd.h>
28#include <signal.h>
29#include <stdlib.h>
30#include <string.h>
31#include <syslog.h>
32#include <time.h>
33#include <unistd.h>
34#include <err.h>
35
36#include "ntpd.h"
37
38#define PFD_PIPE_MAIN0 0
39#define PFD_PIPE_DNS1 1
40#define PFD_SOCK_CTL2 2
41#define PFD_MAX3 3
42
43volatile sig_atomic_t ntp_quit = 0;
44struct imsgbuf *ibuf_main;
45static struct imsgbuf *ibuf_dns;
46struct ntpd_conf *conf;
47struct ctl_conns ctl_conns;
48u_int peer_cnt;
49u_int sensors_cnt;
50extern u_int constraint_cnt;
51
52void ntp_sighdlr(int);
53int ntp_dispatch_imsg(void);
54int ntp_dispatch_imsg_dns(void);
55void peer_add(struct ntp_peer *);
56void peer_remove(struct ntp_peer *);
57int inpool(struct sockaddr_storage *,
58 struct sockaddr_storage[MAX_SERVERS_DNS8], size_t);
59
60void
61ntp_sighdlr(int sig)
62{
63 switch (sig) {
64 case SIGINT2:
65 case SIGTERM15:
66 ntp_quit = 1;
67 break;
68 }
69}
70
71void
72ntp_main(struct ntpd_conf *nconf, struct passwd *pw, int argc, char **argv)
73{
74 int a, b, nfds, i, j, idx_peers, timeout;
75 int nullfd, pipe_dns[2], idx_clients;
76 int ctls;
77 int fd_ctl;
78 u_int pfd_elms = 0, idx2peer_elms = 0;
79 u_int listener_cnt, new_cnt, sent_cnt, trial_cnt;
80 u_int ctl_cnt;
81 struct pollfd *pfd = NULL((void *)0);
82 struct servent *se;
83 struct listen_addr *la;
84 struct ntp_peer *p;
85 struct ntp_peer **idx2peer = NULL((void *)0);
86 struct ntp_sensor *s, *next_s;
87 struct constraint *cstr;
88 struct timespec tp;
89 struct stat stb;
90 struct ctl_conn *cc;
91 time_t nextaction, last_sensor_scan = 0, now;
92 time_t last_action = 0, interval;
93 void *newp;
94
95 if (socketpair(AF_UNIX1, SOCK_STREAM1 | SOCK_CLOEXEC0x8000, PF_UNSPEC0,
1
Assuming the condition is false
2
Taking false branch
96 pipe_dns) == -1)
97 fatal("socketpair");
98
99 start_child(NTPDNS_PROC_NAME"ntp_dns", pipe_dns[1], argc, argv);
100
101 log_init(nconf->debug ? LOG_TO_STDERR(1<<0) : LOG_TO_SYSLOG(1<<1), nconf->verbose,
3
Assuming field 'debug' is not equal to 0
4
'?' condition is true
102 LOG_DAEMON(3<<3));
103 if (!nconf->debug
4.1
Field 'debug' is not equal to 0
&& setsid() == -1)
104 fatal("setsid");
105 log_procinit("ntp");
106
107 if ((se = getservbyname("ntp", "udp")) == NULL((void *)0))
5
Assuming the condition is false
6
Taking false branch
108 fatal("getservbyname");
109
110 /* Start control socket. */
111 if ((fd_ctl = control_init(CTLSOCKET"/var/run/ntpd.sock")) == -1)
7
Assuming the condition is false
8
Taking false branch
112 fatalx("control socket init failed");
113 if (control_listen(fd_ctl) == -1)
9
Assuming the condition is false
10
Taking false branch
114 fatalx("control socket listen failed");
115 if ((nullfd = open("/dev/null", O_RDWR0x0002)) == -1)
11
Assuming the condition is false
12
Taking false branch
116 fatal(NULL((void *)0));
117
118 if (stat(pw->pw_dir, &stb) == -1) {
13
Assuming the condition is false
14
Taking false branch
119 fatal("privsep dir %s could not be opened", pw->pw_dir);
120 }
121 if (stb.st_uid != 0 || (stb.st_mode & (S_IWGRP0000020|S_IWOTH0000002)) != 0) {
15
Assuming field 'st_uid' is equal to 0
16
Assuming the condition is false
17
Taking false branch
122 fatalx("bad privsep dir %s permissions: %o",
123 pw->pw_dir, stb.st_mode);
124 }
125 if (chroot(pw->pw_dir) == -1)
18
Assuming the condition is false
19
Taking false branch
126 fatal("chroot");
127 if (chdir("/") == -1)
20
Assuming the condition is false
21
Taking false branch
128 fatal("chdir(\"/\")");
129
130 if (!nconf->debug
21.1
Field 'debug' is not equal to 0
) {
22
Taking false branch
131 dup2(nullfd, STDIN_FILENO0);
132 dup2(nullfd, STDOUT_FILENO1);
133 dup2(nullfd, STDERR_FILENO2);
134 }
135 close(nullfd);
136
137 setproctitle("ntp engine");
138
139 conf = nconf;
140 setup_listeners(se, conf, &listener_cnt);
141
142 if (setgroups(1, &pw->pw_gid) ||
23
Assuming the condition is false
26
Taking false branch
143 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
24
Assuming the condition is false
144 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
25
Assuming the condition is false
145 fatal("can't drop privileges");
146
147 endservent();
148
149 /* The ntp process will want to open NTP client sockets -> "inet" */
150 if (pledge("stdio inet", NULL((void *)0)) == -1)
27
Assuming the condition is false
28
Taking false branch
151 err(1, "pledge");
152
153 signal(SIGTERM15, ntp_sighdlr);
154 signal(SIGINT2, ntp_sighdlr);
155 signal(SIGPIPE13, SIG_IGN(void (*)(int))1);
156 signal(SIGHUP1, SIG_IGN(void (*)(int))1);
157 signal(SIGCHLD20, SIG_DFL(void (*)(int))0);
158
159 if ((ibuf_main = malloc(sizeof(struct imsgbuf))) == NULL((void *)0))
29
Assuming the condition is false
30
Taking false branch
160 fatal(NULL((void *)0));
161 imsg_init(ibuf_main, PARENT_SOCK_FILENO(2 + 1));
162 if ((ibuf_dns = malloc(sizeof(struct imsgbuf))) == NULL((void *)0))
31
Assuming the condition is false
32
Taking false branch
163 fatal(NULL((void *)0));
164 imsg_init(ibuf_dns, pipe_dns[0]);
165
166 constraint_cnt = 0;
167 conf->constraint_median = 0;
168 conf->constraint_last = getmonotime();
169 TAILQ_FOREACH(cstr, &conf->constraints, entry)for((cstr) = ((&conf->constraints)->tqh_first); (cstr
) != ((void *)0); (cstr) = ((cstr)->entry.tqe_next))
33
Assuming 'cstr' is equal to null
34
Loop condition is false. Execution continues on line 172
170 constraint_cnt += constraint_init(cstr);
171
172 TAILQ_FOREACH(p, &conf->ntp_peers, entry)for((p) = ((&conf->ntp_peers)->tqh_first); (p) != (
(void *)0); (p) = ((p)->entry.tqe_next))
35
Assuming 'p' is equal to null
36
Loop condition is false. Execution continues on line 175
173 client_peer_init(p);
174
175 memset(&conf->status, 0, sizeof(conf->status));
176
177 conf->freq.num = 0;
178 conf->freq.samples = 0;
179 conf->freq.x = 0.0;
180 conf->freq.xx = 0.0;
181 conf->freq.xy = 0.0;
182 conf->freq.y = 0.0;
183 conf->freq.overall_offset = 0.0;
184
185 conf->status.synced = 0;
186 clock_getres(CLOCK_REALTIME0, &tp);
187 b = 1000000000 / tp.tv_nsec; /* convert to Hz */
188 for (a = 0; b > 1; a--, b >>= 1)
37
Assuming 'b' is <= 1
38
Loop condition is false. Execution continues on line 190
189 ;
190 conf->status.precision = a;
191 conf->scale = 1;
192
193 TAILQ_INIT(&ctl_conns)do { (&ctl_conns)->tqh_first = ((void *)0); (&ctl_conns
)->tqh_last = &(&ctl_conns)->tqh_first; } while
(0)
;
39
Loop condition is false. Exiting loop
194 sensor_init();
195
196 log_info("ntp engine ready");
197
198 ctl_cnt = 0;
199 peer_cnt = 0;
200 TAILQ_FOREACH(p, &conf->ntp_peers, entry)for((p) = ((&conf->ntp_peers)->tqh_first); (p) != (
(void *)0); (p) = ((p)->entry.tqe_next))
40
Assuming 'p' is equal to null
41
Loop condition is false. Execution continues on line 203
201 peer_cnt++;
202
203 while (ntp_quit == 0) {
42
Assuming 'ntp_quit' is equal to 0
43
Loop condition is true. Entering loop body
204 if (peer_cnt
43.1
'peer_cnt' is <= 'idx2peer_elms'
> idx2peer_elms) {
44
Taking false branch
205 if ((newp = reallocarray(idx2peer, peer_cnt,
206 sizeof(*idx2peer))) == NULL((void *)0)) {
207 /* panic for now */
208 log_warn("could not resize idx2peer from %u -> "
209 "%u entries", idx2peer_elms, peer_cnt);
210 fatalx("exiting");
211 }
212 idx2peer = newp;
213 idx2peer_elms = peer_cnt;
214 }
215
216 new_cnt = PFD_MAX3 +
217 peer_cnt + listener_cnt + ctl_cnt;
218 if (new_cnt > pfd_elms) {
45
Assuming 'new_cnt' is > 'pfd_elms'
46
Taking true branch
219 if ((newp = reallocarray(pfd, new_cnt,
47
Assuming the condition is false
48
Taking false branch
220 sizeof(*pfd))) == NULL((void *)0)) {
221 /* panic for now */
222 log_warn("could not resize pfd from %u -> "
223 "%u entries", pfd_elms, new_cnt);
224 fatalx("exiting");
225 }
226 pfd = newp;
227 pfd_elms = new_cnt;
228 }
229
230 memset(pfd, 0, sizeof(*pfd) * pfd_elms);
231 memset(idx2peer, 0, sizeof(*idx2peer) * idx2peer_elms);
232 nextaction = getmonotime() + 900;
233 pfd[PFD_PIPE_MAIN0].fd = ibuf_main->fd;
234 pfd[PFD_PIPE_MAIN0].events = POLLIN0x0001;
235 pfd[PFD_PIPE_DNS1].fd = ibuf_dns->fd;
236 pfd[PFD_PIPE_DNS1].events = POLLIN0x0001;
237 pfd[PFD_SOCK_CTL2].fd = fd_ctl;
238 pfd[PFD_SOCK_CTL2].events = POLLIN0x0001;
239
240 i = PFD_MAX3;
241 TAILQ_FOREACH(la, &conf->listen_addrs, entry)for((la) = ((&conf->listen_addrs)->tqh_first); (la)
!= ((void *)0); (la) = ((la)->entry.tqe_next))
{
49
Assuming 'la' is equal to null
50
Loop condition is false. Execution continues on line 247
242 pfd[i].fd = la->fd;
243 pfd[i].events = POLLIN0x0001;
244 i++;
245 }
246
247 idx_peers = i;
248 sent_cnt = trial_cnt = 0;
249 TAILQ_FOREACH(p, &conf->ntp_peers, entry)for((p) = ((&conf->ntp_peers)->tqh_first); (p) != (
(void *)0); (p) = ((p)->entry.tqe_next))
{
51
Assuming 'p' is equal to null
52
Loop condition is false. Execution continues on line 301
250 if (!p->trusted && constraint_cnt &&
251 conf->constraint_median == 0)
252 continue;
253
254 if (p->next > 0 && p->next <= getmonotime()) {
255 if (p->state > STATE_DNS_INPROGRESS)
256 trial_cnt++;
257 if (client_query(p) == 0)
258 sent_cnt++;
259 }
260 if (p->deadline > 0 && p->deadline <= getmonotime()) {
261 timeout = 300;
262 log_debug("no reply from %s received in time, "
263 "next query %ds", log_sockaddr(
264 (struct sockaddr *)&p->addr->ss), timeout);
265 if (p->trustlevel >= TRUSTLEVEL_BADPEER6 &&
266 (p->trustlevel /= 2) < TRUSTLEVEL_BADPEER6)
267 log_info("peer %s now invalid",
268 log_sockaddr(
269 (struct sockaddr *)&p->addr->ss));
270 if (client_nextaddr(p) == 1) {
271 peer_addr_head_clear(p);
272 client_nextaddr(p);
273 }
274 set_next(p, timeout);
275 }
276 if (p->senderrors > MAX_SEND_ERRORS3) {
277 log_debug("failed to send query to %s, "
278 "next query %ds", log_sockaddr(
279 (struct sockaddr *)&p->addr->ss),
280 INTERVAL_QUERY_PATHETIC60);
281 p->senderrors = 0;
282 if (client_nextaddr(p) == 1) {
283 peer_addr_head_clear(p);
284 client_nextaddr(p);
285 }
286 set_next(p, INTERVAL_QUERY_PATHETIC60);
287 }
288 if (p->next > 0 && p->next < nextaction)
289 nextaction = p->next;
290 if (p->deadline > 0 && p->deadline < nextaction)
291 nextaction = p->deadline;
292
293 if (p->state == STATE_QUERY_SENT &&
294 p->query->fd != -1) {
295 pfd[i].fd = p->query->fd;
296 pfd[i].events = POLLIN0x0001;
297 idx2peer[i - idx_peers] = p;
298 i++;
299 }
300 }
301 idx_clients = i;
302
303 if (!TAILQ_EMPTY(&conf->ntp_conf_sensors)(((&conf->ntp_conf_sensors)->tqh_first) == ((void *
)0))
&&
53
Assuming field 'tqh_first' is not equal to null
57
Taking false branch
304 (conf->trusted_sensors || constraint_cnt == 0 ||
54
Assuming field 'trusted_sensors' is 0
55
Assuming 'constraint_cnt' is not equal to 0
305 conf->constraint_median != 0)) {
56
Assuming field 'constraint_median' is equal to 0
306 if (last_sensor_scan == 0 ||
307 last_sensor_scan + SENSOR_SCAN_INTERVAL(1*60) <= getmonotime()) {
308 sensors_cnt = sensor_scan();
309 last_sensor_scan = getmonotime();
310 }
311 if (sensors_cnt == 0 &&
312 nextaction > last_sensor_scan + SENSOR_SCAN_INTERVAL(1*60))
313 nextaction = last_sensor_scan + SENSOR_SCAN_INTERVAL(1*60);
314 sensors_cnt = 0;
315 TAILQ_FOREACH(s, &conf->ntp_sensors, entry)for((s) = ((&conf->ntp_sensors)->tqh_first); (s) !=
((void *)0); (s) = ((s)->entry.tqe_next))
{
316 if (conf->settime && s->offsets[0].offset)
317 priv_settime(s->offsets[0].offset, NULL((void *)0));
318 sensors_cnt++;
319 if (s->next > 0 && s->next < nextaction)
320 nextaction = s->next;
321 }
322 }
323
324 if (conf->settime &&
58
Assuming field 'settime' is 0
325 ((trial_cnt > 0 && sent_cnt == 0) ||
326 (peer_cnt == 0 && sensors_cnt == 0)))
327 priv_settime(0, "no valid peers configured");
328
329 TAILQ_FOREACH(cstr, &conf->constraints, entry)for((cstr) = ((&conf->constraints)->tqh_first); (cstr
) != ((void *)0); (cstr) = ((cstr)->entry.tqe_next))
{
59
Assuming 'cstr' is equal to null
60
Loop condition is false. Execution continues on line 334
330 if (constraint_query(cstr) == -1)
331 continue;
332 }
333
334 if (ibuf_main->w.queued > 0)
61
Assuming field 'queued' is <= 0
62
Taking false branch
335 pfd[PFD_PIPE_MAIN0].events |= POLLOUT0x0004;
336 if (ibuf_dns->w.queued > 0)
63
Assuming field 'queued' is <= 0
64
Taking false branch
337 pfd[PFD_PIPE_DNS1].events |= POLLOUT0x0004;
338
339 TAILQ_FOREACH(cc, &ctl_conns, entry)for((cc) = ((&ctl_conns)->tqh_first); (cc) != ((void *
)0); (cc) = ((cc)->entry.tqe_next))
{
65
Assuming 'cc' is equal to null
66
Loop condition is false. Execution continues on line 346
340 pfd[i].fd = cc->ibuf.fd;
341 pfd[i].events = POLLIN0x0001;
342 if (cc->ibuf.w.queued > 0)
343 pfd[i].events |= POLLOUT0x0004;
344 i++;
345 }
346 ctls = i;
347
348 now = getmonotime();
349 timeout = nextaction - now;
350 if (timeout < 0)
67
Assuming 'timeout' is >= 0
68
Taking false branch
351 timeout = 0;
352
353 if ((nfds = poll(pfd, i, timeout ? timeout * 1000 : 1)) == -1)
69
Assuming 'timeout' is 0
70
'?' condition is false
71
Assuming the condition is false
72
Taking false branch
354 if (errno(*__errno()) != EINTR4) {
355 log_warn("poll error");
356 ntp_quit = 1;
357 }
358
359 if (nfds > 0 && (pfd[PFD_PIPE_MAIN0].revents & POLLOUT0x0004))
73
Assuming 'nfds' is > 0
74
Assuming the condition is false
75
Taking false branch
360 if (msgbuf_write(&ibuf_main->w) <= 0 &&
361 errno(*__errno()) != EAGAIN35) {
362 log_warn("pipe write error (to parent)");
363 ntp_quit = 1;
364 }
365
366 if (nfds
75.1
'nfds' is > 0
> 0 && pfd[PFD_PIPE_MAIN0].revents & (POLLIN0x0001|POLLERR0x0008)) {
76
Assuming the condition is false
77
Taking false branch
367 nfds--;
368 if (ntp_dispatch_imsg() == -1) {
369 log_debug("pipe read error (from main)");
370 ntp_quit = 1;
371 }
372 }
373
374 if (nfds
77.1
'nfds' is > 0
> 0 && (pfd[PFD_PIPE_DNS1].revents & POLLOUT0x0004))
78
Assuming the condition is false
79
Taking false branch
375 if (msgbuf_write(&ibuf_dns->w) <= 0 &&
376 errno(*__errno()) != EAGAIN35) {
377 log_warn("pipe write error (to dns engine)");
378 ntp_quit = 1;
379 }
380
381 if (nfds
79.1
'nfds' is > 0
> 0 && pfd[PFD_PIPE_DNS1].revents & (POLLIN0x0001|POLLERR0x0008)) {
80
Assuming the condition is true
81
Taking true branch
382 nfds--;
383 if (ntp_dispatch_imsg_dns() == -1) {
82
Calling 'ntp_dispatch_imsg_dns'
384 log_warn("pipe read error (from dns engine)");
385 ntp_quit = 1;
386 }
387 }
388
389 if (nfds > 0 && pfd[PFD_SOCK_CTL2].revents & (POLLIN0x0001|POLLERR0x0008)) {
390 nfds--;
391 ctl_cnt += control_accept(fd_ctl);
392 }
393
394 for (j = PFD_MAX3; nfds > 0 && j < idx_peers; j++)
395 if (pfd[j].revents & (POLLIN0x0001|POLLERR0x0008)) {
396 nfds--;
397 if (server_dispatch(pfd[j].fd, conf) == -1) {
398 log_warn("pipe write error (conf)");
399 ntp_quit = 1;
400 }
401 }
402
403 for (; nfds > 0 && j < idx_clients; j++) {
404 if (pfd[j].revents & (POLLIN0x0001|POLLERR0x0008)) {
405 struct ntp_peer *pp = idx2peer[j - idx_peers];
406
407 nfds--;
408 switch (client_dispatch(pp, conf->settime,
409 conf->automatic)) {
410 case -1:
411 log_debug("no reply from %s "
412 "received", log_sockaddr(
413 (struct sockaddr *) &pp->addr->ss));
414 if (pp->trustlevel >=
415 TRUSTLEVEL_BADPEER6 &&
416 (pp->trustlevel /= 2) <
417 TRUSTLEVEL_BADPEER6)
418 log_info("peer %s now invalid",
419 log_sockaddr(
420 (struct sockaddr *)
421 &pp->addr->ss));
422 break;
423 case 0: /* invalid replies are ignored */
424 break;
425 case 1:
426 last_action = now;
427 break;
428 }
429 }
430 }
431
432 for (; nfds > 0 && j < ctls; j++) {
433 nfds -= control_dispatch_msg(&pfd[j], &ctl_cnt);
434 }
435
436 for (s = TAILQ_FIRST(&conf->ntp_sensors)((&conf->ntp_sensors)->tqh_first); s != NULL((void *)0);
437 s = next_s) {
438 next_s = TAILQ_NEXT(s, entry)((s)->entry.tqe_next);
439 if (s->next <= now) {
440 last_action = now;
441 sensor_query(s);
442 }
443 }
444
445 /*
446 * Compute maximum of scale_interval(INTERVAL_QUERY_NORMAL),
447 * if we did not process a time message for three times that
448 * interval, stop advertising we're synced.
449 */
450 interval = INTERVAL_QUERY_NORMAL30 * conf->scale;
451 interval += SCALE_INTERVAL(interval)((5) > ((interval) / 10) ? (5) : ((interval) / 10)) - 1;
452 if (conf->status.synced && last_action + 3 * interval < now) {
453 log_info("clock is now unsynced due to lack of replies");
454 conf->status.synced = 0;
455 conf->scale = 1;
456 priv_dns(IMSG_UNSYNCED, NULL((void *)0), 0);
457 }
458 }
459
460 msgbuf_write(&ibuf_main->w);
461 msgbuf_clear(&ibuf_main->w);
462 free(ibuf_main);
463 msgbuf_write(&ibuf_dns->w);
464 msgbuf_clear(&ibuf_dns->w);
465 free(ibuf_dns);
466
467 log_info("ntp engine exiting");
468 exit(0);
469}
470
471int
472ntp_dispatch_imsg(void)
473{
474 struct imsg imsg;
475 int n;
476
477 if (((n = imsg_read(ibuf_main)) == -1 && errno(*__errno()) != EAGAIN35) || n == 0)
478 return (-1);
479
480 for (;;) {
481 if ((n = imsg_get(ibuf_main, &imsg)) == -1)
482 return (-1);
483
484 if (n == 0)
485 break;
486
487 switch (imsg.hdr.type) {
488 case IMSG_ADJTIME:
489 memcpy(&n, imsg.data, sizeof(n));
490 if (n == 1 && !conf->status.synced) {
491 log_info("clock is now synced");
492 conf->status.synced = 1;
493 priv_dns(IMSG_SYNCED, NULL((void *)0), 0);
494 constraint_reset();
495 } else if (n == 0 && conf->status.synced) {
496 log_info("clock is now unsynced");
497 conf->status.synced = 0;
498 priv_dns(IMSG_UNSYNCED, NULL((void *)0), 0);
499 }
500 break;
501 case IMSG_CONSTRAINT_RESULT:
502 constraint_msg_result(imsg.hdr.peerid,
503 imsg.data, imsg.hdr.len - IMSG_HEADER_SIZEsizeof(struct imsg_hdr));
504 break;
505 case IMSG_CONSTRAINT_CLOSE:
506 constraint_msg_close(imsg.hdr.peerid,
507 imsg.data, imsg.hdr.len - IMSG_HEADER_SIZEsizeof(struct imsg_hdr));
508 break;
509 default:
510 break;
511 }
512 imsg_free(&imsg);
513 }
514 return (0);
515}
516
517int
518inpool(struct sockaddr_storage *a,
519 struct sockaddr_storage old[MAX_SERVERS_DNS8], size_t n)
520{
521 size_t i;
522
523 for (i = 0; i < n; i++) {
524 if (a->ss_family != old[i].ss_family)
525 continue;
526 if (a->ss_family == AF_INET2) {
527 if (((struct sockaddr_in *)a)->sin_addr.s_addr ==
528 ((struct sockaddr_in *)&old[i])->sin_addr.s_addr)
529 return 1;
530 } else if (memcmp(&((struct sockaddr_in6 *)a)->sin6_addr,
531 &((struct sockaddr_in6 *)&old[i])->sin6_addr,
532 sizeof(struct sockaddr_in6)) == 0) {
533 return 1;
534 }
535 }
536 return 0;
537}
538
539int
540ntp_dispatch_imsg_dns(void)
541{
542 struct imsg imsg;
543 struct sockaddr_storage existing[MAX_SERVERS_DNS8];
544 struct ntp_peer *peer, *npeer, *tmp;
545 u_int16_t dlen;
546 u_char *p;
547 struct ntp_addr *h;
548 size_t addrcount, peercount;
549 int n;
550
551 if (((n = imsg_read(ibuf_dns)) == -1 && errno(*__errno()) != EAGAIN35) || n == 0)
83
Assuming the condition is false
84
Assuming 'n' is not equal to 0
85
Taking false branch
552 return (-1);
553
554 for (;;) {
86
Loop condition is true. Entering loop body
128
Loop condition is true. Entering loop body
555 if ((n = imsg_get(ibuf_dns, &imsg)) == -1)
87
Assuming the condition is false
88
Taking false branch
129
Assuming the condition is false
130
Taking false branch
556 return (-1);
557
558 if (n == 0)
89
Assuming 'n' is not equal to 0
90
Taking false branch
131
Assuming 'n' is not equal to 0
132
Taking false branch
559 break;
560
561 switch (imsg.hdr.type) {
91
Control jumps to 'case IMSG_HOST_DNS:' at line 562
133
Control jumps to 'case IMSG_HOST_DNS:' at line 562
562 case IMSG_HOST_DNS:
563 TAILQ_FOREACH(peer, &conf->ntp_peers, entry)for((peer) = ((&conf->ntp_peers)->tqh_first); (peer
) != ((void *)0); (peer) = ((peer)->entry.tqe_next))
92
Assuming 'peer' is not equal to null
93
Loop condition is true. Entering loop body
134
Loop condition is true. Entering loop body
564 if (peer->id == imsg.hdr.peerid)
94
Assuming field 'id' is equal to field 'peerid'
95
Taking true branch
135
Use of memory after it is freed
565 break;
96
Execution continues on line 566
566 if (peer
96.1
'peer' is not equal to NULL
== NULL((void *)0)) {
97
Taking false branch
567 log_warnx("IMSG_HOST_DNS with invalid peerID");
568 break;
569 }
570 if (peer->addr != NULL((void *)0)) {
98
Assuming field 'addr' is equal to NULL
99
Taking false branch
571 log_warnx("IMSG_HOST_DNS but addr != NULL!");
572 break;
573 }
574
575 if (peer->addr_head.pool) {
100
Assuming field 'pool' is not equal to 0
101
Taking true branch
576 n = 0;
577 peercount = 0;
578
579 TAILQ_FOREACH_SAFE(npeer, &conf->ntp_peers,for ((npeer) = ((&conf->ntp_peers)->tqh_first); (npeer
) != ((void *)0) && ((tmp) = ((npeer)->entry.tqe_next
), 1); (npeer) = (tmp))
102
Loop condition is true. Entering loop body
106
Assuming 'npeer' is equal to null
580 entry, tmp)for ((npeer) = ((&conf->ntp_peers)->tqh_first); (npeer
) != ((void *)0) && ((tmp) = ((npeer)->entry.tqe_next
), 1); (npeer) = (tmp))
{
581 if (npeer->addr_head.pool
102.1
'npeer->addr_head.pool' is equal to 'peer->addr_head.pool'
!=
103
Taking false branch
582 peer->addr_head.pool)
583 continue;
584 peercount++;
585 if (npeer->id
103.1
'npeer->id' is equal to 'peer->id'
== peer->id)
104
Taking true branch
586 continue;
105
Execution continues on line 579
587 if (npeer->addr != NULL((void *)0))
588 existing[n++] = npeer->addr->ss;
589 }
590 }
591
592 dlen = imsg.hdr.len - IMSG_HEADER_SIZEsizeof(struct imsg_hdr);
593 if (dlen == 0) { /* no data -> temp error */
107
Assuming 'dlen' is not equal to 0
108
Taking false branch
594 log_warnx("DNS lookup tempfail");
595 peer->state = STATE_DNS_TEMPFAIL;
596 if (conf->tmpfail++ == TRIES_AUTO_DNSFAIL4)
597 priv_settime(0, "of dns failures");
598 break;
599 }
600
601 p = (u_char *)imsg.data;
602 addrcount = dlen / (sizeof(struct sockaddr_storage) +
603 sizeof(int));
604
605 while (dlen >= sizeof(struct sockaddr_storage) +
109
Assuming the condition is true
110
Loop condition is true. Entering loop body
117
Assuming the condition is false
118
Loop condition is false. Execution continues on line 651
606 sizeof(int)) {
607 if ((h = calloc(1, sizeof(struct ntp_addr))) ==
111
Assuming the condition is false
112
Taking false branch
608 NULL((void *)0))
609 fatal(NULL((void *)0));
610 memcpy(&h->ss, p, sizeof(h->ss));
611 p += sizeof(h->ss);
612 dlen -= sizeof(h->ss);
613 memcpy(&h->notauth, p, sizeof(int));
614 p += sizeof(int);
615 dlen -= sizeof(int);
616 if (peer->addr_head.pool
112.1
Field 'pool' is not equal to 0
) {
113
Taking true branch
617 if (peercount > addrcount) {
114
Assuming 'peercount' is > 'addrcount'
115
Taking true branch
618 free(h);
619 continue;
116
Execution continues on line 605
620 }
621 if (inpool(&h->ss, existing,
622 n)) {
623 free(h);
624 continue;
625 }
626 log_debug("Adding address %s to %s",
627 log_sockaddr((struct sockaddr *)
628 &h->ss), peer->addr_head.name);
629 npeer = new_peer();
630 npeer->weight = peer->weight;
631 npeer->query_addr4 = peer->query_addr4;
632 npeer->query_addr6 = peer->query_addr6;
633 h->next = NULL((void *)0);
634 npeer->addr = h;
635 npeer->addr_head.a = h;
636 npeer->addr_head.name =
637 peer->addr_head.name;
638 npeer->addr_head.pool =
639 peer->addr_head.pool;
640 client_peer_init(npeer);
641 npeer->state = STATE_DNS_DONE;
642 peer_add(npeer);
643 peercount++;
644 } else {
645 h->next = peer->addr;
646 peer->addr = h;
647 peer->addr_head.a = peer->addr;
648 peer->state = STATE_DNS_DONE;
649 }
650 }
651 if (dlen != 0)
119
Assuming 'dlen' is equal to 0
120
Taking false branch
652 fatalx("IMSG_HOST_DNS: dlen != 0");
653 if (peer->addr_head.pool
120.1
Field 'pool' is not equal to 0
)
121
Taking true branch
654 peer_remove(peer);
122
Calling 'peer_remove'
126
Returning; memory was released via 1st parameter
655 else
656 client_addr_init(peer);
657 break;
127
Execution continues on line 673
658 case IMSG_CONSTRAINT_DNS:
659 constraint_msg_dns(imsg.hdr.peerid,
660 imsg.data, imsg.hdr.len - IMSG_HEADER_SIZEsizeof(struct imsg_hdr));
661 break;
662 case IMSG_PROBE_ROOT:
663 dlen = imsg.hdr.len - IMSG_HEADER_SIZEsizeof(struct imsg_hdr);
664 if (dlen != sizeof(int))
665 fatalx("IMSG_PROBE_ROOT");
666 memcpy(&n, imsg.data, sizeof(int));
667 if (n < 0)
668 priv_settime(0, "dns probe failed");
669 break;
670 default:
671 break;
672 }
673 imsg_free(&imsg);
674 }
675 return (0);
676}
677
678void
679peer_add(struct ntp_peer *p)
680{
681 TAILQ_INSERT_TAIL(&conf->ntp_peers, p, entry)do { (p)->entry.tqe_next = ((void *)0); (p)->entry.tqe_prev
= (&conf->ntp_peers)->tqh_last; *(&conf->ntp_peers
)->tqh_last = (p); (&conf->ntp_peers)->tqh_last =
&(p)->entry.tqe_next; } while (0)
;
682 peer_cnt++;
683}
684
685void
686peer_remove(struct ntp_peer *p)
687{
688 TAILQ_REMOVE(&conf->ntp_peers, p, entry)do { if (((p)->entry.tqe_next) != ((void *)0)) (p)->entry
.tqe_next->entry.tqe_prev = (p)->entry.tqe_prev; else (
&conf->ntp_peers)->tqh_last = (p)->entry.tqe_prev
; *(p)->entry.tqe_prev = (p)->entry.tqe_next; ; ; } while
(0)
;
123
Taking false branch
124
Loop condition is false. Exiting loop
689 free(p);
125
Memory is released
690 peer_cnt--;
691}
692
693void
694peer_addr_head_clear(struct ntp_peer *p)
695{
696 host_dns_free(p->addr_head.a);
697 p->addr_head.a = NULL((void *)0);
698 p->addr = NULL((void *)0);
699}
700
701static void
702priv_adjfreq(double offset)
703{
704 double curtime, freq;
705
706 if (!conf->status.synced){
707 conf->freq.samples = 0;
708 return;
709 }
710
711 conf->freq.samples++;
712
713 if (conf->freq.samples <= 0)
714 return;
715
716 conf->freq.overall_offset += offset;
717 offset = conf->freq.overall_offset;
718
719 curtime = gettime_corrected();
720 conf->freq.xy += offset * curtime;
721 conf->freq.x += curtime;
722 conf->freq.y += offset;
723 conf->freq.xx += curtime * curtime;
724
725 if (conf->freq.samples % FREQUENCY_SAMPLES8 != 0)
726 return;
727
728 freq =
729 (conf->freq.xy - conf->freq.x * conf->freq.y / conf->freq.samples)
730 /
731 (conf->freq.xx - conf->freq.x * conf->freq.x / conf->freq.samples);
732
733 if (freq > MAX_FREQUENCY_ADJUST128e-5)
734 freq = MAX_FREQUENCY_ADJUST128e-5;
735 else if (freq < -MAX_FREQUENCY_ADJUST128e-5)
736 freq = -MAX_FREQUENCY_ADJUST128e-5;
737
738 imsg_compose(ibuf_main, IMSG_ADJFREQ, 0, 0, -1, &freq, sizeof(freq));
739 conf->filters |= FILTER_ADJFREQ0x01;
740 conf->freq.xy = 0.0;
741 conf->freq.x = 0.0;
742 conf->freq.y = 0.0;
743 conf->freq.xx = 0.0;
744 conf->freq.samples = 0;
745 conf->freq.overall_offset = 0.0;
746 conf->freq.num++;
747}
748
749int
750priv_adjtime(void)
751{
752 struct ntp_peer *p;
753 struct ntp_sensor *s;
754 int offset_cnt = 0, i = 0, j;
755 struct ntp_offset **offsets;
756 double offset_median;
757
758 TAILQ_FOREACH(p, &conf->ntp_peers, entry)for((p) = ((&conf->ntp_peers)->tqh_first); (p) != (
(void *)0); (p) = ((p)->entry.tqe_next))
{
759 if (p->trustlevel < TRUSTLEVEL_BADPEER6)
760 continue;
761 if (!p->update.good)
762 return (1);
763 offset_cnt += p->weight;
764 }
765
766 TAILQ_FOREACH(s, &conf->ntp_sensors, entry)for((s) = ((&conf->ntp_sensors)->tqh_first); (s) !=
((void *)0); (s) = ((s)->entry.tqe_next))
{
767 if (!s->update.good)
768 continue;
769 offset_cnt += s->weight;
770 }
771
772 if (offset_cnt == 0)
773 return (1);
774
775 if ((offsets = calloc(offset_cnt, sizeof(struct ntp_offset *))) == NULL((void *)0))
776 fatal("calloc priv_adjtime");
777
778 TAILQ_FOREACH(p, &conf->ntp_peers, entry)for((p) = ((&conf->ntp_peers)->tqh_first); (p) != (
(void *)0); (p) = ((p)->entry.tqe_next))
{
779 if (p->trustlevel < TRUSTLEVEL_BADPEER6)
780 continue;
781 for (j = 0; j < p->weight; j++)
782 offsets[i++] = &p->update;
783 }
784
785 TAILQ_FOREACH(s, &conf->ntp_sensors, entry)for((s) = ((&conf->ntp_sensors)->tqh_first); (s) !=
((void *)0); (s) = ((s)->entry.tqe_next))
{
786 if (!s->update.good)
787 continue;
788 for (j = 0; j < s->weight; j++)
789 offsets[i++] = &s->update;
790 }
791
792 qsort(offsets, offset_cnt, sizeof(struct ntp_offset *), offset_compare);
793
794 i = offset_cnt / 2;
795 if (offset_cnt % 2 == 0)
796 if (offsets[i - 1]->delay < offsets[i]->delay)
797 i -= 1;
798 offset_median = offsets[i]->offset;
799 conf->status.rootdelay = offsets[i]->delay;
800 conf->status.stratum = offsets[i]->status.stratum;
801 conf->status.leap = offsets[i]->status.leap;
802
803 imsg_compose(ibuf_main, IMSG_ADJTIME, 0, 0, -1,
804 &offset_median, sizeof(offset_median));
805
806 priv_adjfreq(offset_median);
807
808 conf->status.reftime = gettime();
809 conf->status.stratum++; /* one more than selected peer */
810 if (conf->status.stratum > NTP_MAXSTRATUM15)
811 conf->status.stratum = NTP_MAXSTRATUM15;
812 update_scale(offset_median);
813
814 conf->status.refid = offsets[i]->status.send_refid;
815
816 free(offsets);
817
818 TAILQ_FOREACH(p, &conf->ntp_peers, entry)for((p) = ((&conf->ntp_peers)->tqh_first); (p) != (
(void *)0); (p) = ((p)->entry.tqe_next))
{
819 for (i = 0; i < OFFSET_ARRAY_SIZE8; i++)
820 p->reply[i].offset -= offset_median;
821 p->update.good = 0;
822 }
823 TAILQ_FOREACH(s, &conf->ntp_sensors, entry)for((s) = ((&conf->ntp_sensors)->tqh_first); (s) !=
((void *)0); (s) = ((s)->entry.tqe_next))
{
824 for (i = 0; i < SENSOR_OFFSETS6; i++)
825 s->offsets[i].offset -= offset_median;
826 s->update.offset -= offset_median;
827 }
828
829 return (0);
830}
831
832int
833offset_compare(const void *aa, const void *bb)
834{
835 const struct ntp_offset * const *a;
836 const struct ntp_offset * const *b;
837
838 a = aa;
839 b = bb;
840
841 if ((*a)->offset < (*b)->offset)
842 return (-1);
843 else if ((*a)->offset > (*b)->offset)
844 return (1);
845 else
846 return (0);
847}
848
849void
850priv_settime(double offset, char *msg)
851{
852 if (offset == 0)
853 log_info("cancel settime because %s", msg);
854 imsg_compose(ibuf_main, IMSG_SETTIME, 0, 0, -1,
855 &offset, sizeof(offset));
856 conf->settime = 0;
857}
858
859void
860priv_dns(int cmd, char *name, u_int32_t peerid)
861{
862 u_int16_t dlen = 0;
863
864 if (name != NULL((void *)0))
865 dlen = strlen(name) + 1;
866 imsg_compose(ibuf_dns, cmd, peerid, 0, -1, name, dlen);
867}
868
869void
870update_scale(double offset)
871{
872 offset += getoffset();
873 if (offset < 0)
874 offset = -offset;
875
876 if (offset > QSCALE_OFF_MAX0.050 || !conf->status.synced ||
877 conf->freq.num < 3)
878 conf->scale = 1;
879 else if (offset < QSCALE_OFF_MIN0.001)
880 conf->scale = QSCALE_OFF_MAX0.050 / QSCALE_OFF_MIN0.001;
881 else
882 conf->scale = QSCALE_OFF_MAX0.050 / offset;
883}
884
885time_t
886scale_interval(time_t requested)
887{
888 time_t interval, r;
889
890 interval = requested * conf->scale;
891 r = arc4random_uniform(SCALE_INTERVAL(interval)((5) > ((interval) / 10) ? (5) : ((interval) / 10)));
892 return (interval + r);
893}
894
895time_t
896error_interval(void)
897{
898 time_t interval, r;
899
900 interval = INTERVAL_QUERY_PATHETIC60 * QSCALE_OFF_MAX0.050 / QSCALE_OFF_MIN0.001;
901 r = arc4random_uniform(interval / 10);
902 return (interval + r);
903}