Bug Summary

File:src/usr.sbin/nsd/verify.c
Warning:line 468, column 16
Access to field 'pid' results in a dereference of a null pointer (loaded from variable 'verifier')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name verify.c -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 -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -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/nsd/obj -resource-dir /usr/local/llvm16/lib/clang/16 -I . -I /usr/src/usr.sbin/nsd -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/nsd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -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/scan/2024-01-11-140451-98009-1 -x c /usr/src/usr.sbin/nsd/verify.c
1/*
2 * verify.c -- running verifiers and serving the zone to be verified.
3 *
4 * Copyright (c) 2012-2020, NLnet Labs. All rights reserved.
5 *
6 * See LICENSE for the license.
7 *
8 */
9
10#include "config.h"
11
12#include <assert.h>
13#include <ctype.h>
14#include <errno(*__errno()).h>
15#include <stdarg.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#ifdef HAVE_SYSLOG_H1
20#include <syslog.h>
21#endif /* HAVE_SYSLOG_H */
22#include <unistd.h>
23#include <fcntl.h>
24#include <sys/wait.h>
25
26#include "region-allocator.h"
27#include "namedb.h"
28#include "nsd.h"
29#include "options.h"
30#include "difffile.h"
31#include "verify.h"
32#include "popen3.h"
33
34struct zone *verify_next_zone(struct nsd *nsd, struct zone *zone)
35{
36 int verify;
37 struct radnode *node;
38
39 if(zone != NULL((void *)0)) {
40 node = radix_next(zone->node);
41 } else {
42 node = radix_first(nsd->db->zonetree);
43 }
44
45 while(node != NULL((void *)0)) {
46 zone = (struct zone *)node->elem;
47 verify = zone->opts->pattern->verify_zone;
48 if(verify == VERIFY_ZONE_INHERIT(2)) {
49 verify = nsd->options->verify_zones;
50 }
51 if(verify && zone->is_updated && !zone->is_checked) {
52 return zone;
53 }
54 node = radix_next(node);
55 }
56
57 return NULL((void *)0);
58}
59
60static inline ssize_t fill_buffer(struct verifier_stream *stream)
61{
62 ssize_t cnt = 0;
63
64 assert(stream)((void)0);
65 assert(stream->fd != -1)((void)0);
66 assert(stream->cnt <= LOGBUFSIZE)((void)0);
67 assert(stream->off <= stream->cnt)((void)0);
68
69 // move data to start of buffer assuming all complete lines are printed
70 if (stream->off) {
71 size_t len = stream->cnt - stream->off;
72 memmove(stream->buf, stream->buf + stream->off, len);
73 stream->off = 0;
74 stream->cnt = len;
75 stream->buf[stream->cnt] = '\0'; // always null-terminate
76 }
77
78 // read data if space is available
79 cnt = read(stream->fd, stream->buf + stream->cnt, LOGBUFSIZE((512 -40) * 2) - stream->cnt);
80 if (cnt > 0)
81 stream->cnt += (size_t)cnt;
82 assert(stream->cnt <= LOGBUFSIZE)((void)0);
83 assert(stream->off <= stream->cnt)((void)0);
84 stream->buf[stream->cnt] = '\0'; // always null-terminate
85
86 return cnt;
87}
88
89static inline size_t print_line(struct verifier_stream *stream, int eof)
90{
91 char *eol = NULL((void *)0);
92 size_t len;
93 const char *fmt;
94
95 if (stream->cnt == 0)
96 return 0;
97 assert(stream->off <= stream->cnt)((void)0);
98 if (stream->off == stream->cnt)
99 return 0;
100
101 // try to locate natural line break
102 assert(stream->buf[stream->cnt] == '\0')((void)0);
103 if ((eol = strchr(stream->buf + stream->off, '\n'))) {
104 len = eol - (stream->buf + stream->off);
105 } else {
106 len = stream->cnt - stream->off;
107 }
108
109 assert(len <= (stream->cnt - stream->off))((void)0);
110 // wait for buffer to contain a full line except on eof
111 if (len < LOGLINELEN(512 -40) && !eol && !eof)
112 return 0;
113
114 if (len > LOGLINELEN(512 -40)) {
115 fmt = stream->cut ? "verifier: .. %.*s .." : "verifier: %.*s ..";
116 len = LOGLINELEN(512 -40); // remainder printed next iteration
117 stream->cut = 1;
118 } else {
119 fmt = stream->cut ? "verifier: .. %.*s" : "verifier: %.*s";
120 stream->cut = 0;
121 }
122 log_msg(stream->priority, fmt, len, stream->buf + stream->off);
123
124 stream->off += len + (eol != NULL((void *)0));
125 assert(stream->off <= stream->cnt)((void)0);
126 return len;
127}
128
129/*
130 * Log verifier output on STDOUT and STDERR. Lines longer than LOGLINELEN are
131 * split over multiple lines. Line-breaks are indicated in the log with "...".
132 */
133static void verify_handle_stream(int fd, short event, void *arg)
134{
135 int eof = 0;
136 ssize_t cnt;
137 struct verifier *verifier;
138 struct verifier_stream *stream;
139
140 assert(event & EV_READ)((void)0);
141 assert(arg != NULL)((void)0);
142
143 verifier = (struct verifier *)arg;
144 if (fd == verifier->output_stream.fd) {
145 stream = &verifier->output_stream;
146 } else {
147 assert(fd == verifier->error_stream.fd)((void)0);
148 stream = &verifier->error_stream;
149 }
150
151 assert(stream)((void)0);
152 assert(stream->fd != -1)((void)0);
153
154 do {
155 cnt = fill_buffer(stream);
156 eof = !cnt || (cnt < 0 && errno(*__errno()) != EAGAIN35 && errno(*__errno()) != EINTR4);
157 while (print_line(stream, eof)) ;
158 } while (cnt > 0);
159
160 if(eof) {
161 event_del(&stream->event);
162 close(stream->fd);
163 stream->fd = -1;
164 }
165}
166
167static void kill_verifier(struct verifier *verifier)
168{
169 assert(verifier != NULL)((void)0);
170 assert(verifier->zone != NULL)((void)0);
171
172 if(kill(verifier->pid, SIGTERM15) == -1) {
173 log_msg(LOG_ERR3, "verify: cannot kill verifier for "
174 "zone %s (pid %d): %s",
175 verifier->zone->opts->name,
176 verifier->pid,
177 strerror(errno(*__errno())));
178 }
179}
180
181static void close_stream(struct verifier *verifier, struct verifier_stream *stream)
182{
183 if (stream->fd == -1)
184 return;
185 verify_handle_stream(stream->fd, EV_READ0x02, verifier);
186 if (stream->fd == -1)
187 return;
188 event_del(&stream->event);
189 close(stream->fd);
190 stream->fd = -1;
191}
192
193static void close_verifier(struct verifier *verifier)
194{
195 /* unregister events and close streams (in that order) */
196 if(verifier->timeout.tv_sec > 0) {
197 event_del(&verifier->timeout_event);
198 verifier->timeout.tv_sec = 0;
199 verifier->timeout.tv_usec = 0;
200 }
201
202 if(verifier->zone_feed.fh != NULL((void *)0)) {
203 event_del(&verifier->zone_feed.event);
204 fclose(verifier->zone_feed.fh);
205 verifier->zone_feed.fh = NULL((void *)0);
206 region_destroy(verifier->zone_feed.region);
207 }
208
209 close_stream(verifier, &verifier->error_stream);
210 close_stream(verifier, &verifier->output_stream);
211
212 verifier->zone->is_ok = verifier->was_ok;
213 verifier->pid = -1;
214 verifier->zone = NULL((void *)0);
215}
216
217/*
218 * Feed zone to verifier over STDIN as it becomes available.
219 */
220static void verify_handle_feed(int fd, short event, void *arg)
221{
222 struct verifier *verifier;
223 struct rr *rr;
224
225 (void)fd;
226 assert(event == EV_WRITE)((void)0);
227 assert(arg != NULL)((void)0);
228
229 verifier = (struct verifier *)arg;
230 if((rr = zone_rr_iter_next(&verifier->zone_feed.rriter)) != NULL((void *)0)) {
231 print_rr(verifier->zone_feed.fh,
232 verifier->zone_feed.rrprinter,
233 rr,
234 verifier->zone_feed.region,
235 verifier->zone_feed.buffer);
236 } else {
237 event_del(&verifier->zone_feed.event);
238 fclose(verifier->zone_feed.fh);
239 verifier->zone_feed.fh = NULL((void *)0);
240 region_destroy(verifier->zone_feed.region);
241 }
242}
243
244/*
245 * This handler will be called when a verifier-timeout alarm goes off. It just
246 * kills the verifier. server_verify_zones will make sure the zone will be
247 * considered bad.
248 */
249void verify_handle_timeout(int fd, short event, void *arg)
250{
251 struct verifier *verifier;
252
253 (void)fd;
254 assert(event & EV_TIMEOUT)((void)0);
255 assert(arg != NULL)((void)0);
256
257 verifier = (struct verifier *)arg;
258 verifier->zone->is_bad = 1;
259
260 log_msg(LOG_ERR3, "verify: verifier for zone %s (pid %d) timed out",
261 verifier->zone->opts->name, verifier->pid);
262
263 /* kill verifier, process reaped by exit handler */
264 kill_verifier(verifier);
265}
266
267void verify_handle_signal(int sig, short event, void *arg)
268{
269 char buf[1] = { '\0' };
270 struct nsd *nsd;
271
272 assert(sig == SIGCHLD)((void)0);
273 assert(event & EV_SIGNAL)((void)0);
274 assert(arg != NULL)((void)0);
275
276 nsd = (struct nsd *)arg;
277 if(write(nsd->verifier_pipe[1], buf, sizeof(buf)) == -1) {
278 log_msg(LOG_ERR3, "verify_handle_signal: write failed: %s",
279 strerror(errno(*__errno())));
280 }
281}
282
283/*
284 * Reap process and update status of respective zone based on the exit code
285 * of a verifier. Everything from STDOUT and STDERR still available is read and
286 * written to the log as it might contain valuable information.
287 *
288 * NOTE: A timeout might have caused the verifier to be terminated.
289 */
290void verify_handle_exit(int fd, short event, void *arg)
291{
292 int wstatus;
293 pid_t pid;
294 struct nsd *nsd;
295 char buf[1];
296
297 assert(event & EV_READ)((void)0);
298 assert(arg != NULL)((void)0);
299
300 nsd = (struct nsd *)arg;
301
302 if(read(fd, buf, sizeof(buf)) == -1) {
1
Assuming the condition is false
303 if(errno(*__errno()) != EAGAIN35 && errno(*__errno()) != EINTR4 && errno(*__errno()) != EWOULDBLOCK35)
304 log_msg(LOG_ERR3, "verify_handle_exit: read failed: %s",
305 strerror(errno(*__errno())));
306 }
307
308 while(((pid = waitpid(-1, &wstatus, WNOHANG0x01)) == -1 && errno(*__errno()) == EINTR4)
2
Assuming the condition is false
309 || (pid > 0))
3
Assuming 'pid' is <= 0
310 {
311 struct verifier *verifier = NULL((void *)0);
312
313 for(size_t i = 0; !verifier && i < nsd->verifier_limit; i++) {
314 if(nsd->verifiers[i].zone != NULL((void *)0) &&
315 nsd->verifiers[i].pid == pid)
316 {
317 verifier = &nsd->verifiers[i];
318 }
319 }
320
321 if(verifier == NULL((void *)0)) {
322 continue;
323 }
324
325 if(!WIFEXITED(wstatus)(((wstatus) & 0177) == 0)) {
326 log_msg(LOG_ERR3, "verify: verifier for zone %s "
327 "(pid %d) exited abnormally",
328 verifier->zone->opts->name, pid);
329 } else {
330 int priority = LOG_INFO6;
331 int status = WEXITSTATUS(wstatus)(int)(((unsigned)(wstatus) >> 8) & 0xff);
332 if(status != 0) {
333 priority = LOG_ERR3;
334 verifier->zone->is_bad = 1;
335 }
336 log_msg(priority, "verify: verifier for zone %s "
337 "(pid %d) exited with %d",
338 verifier->zone->opts->name, pid, status);
339 }
340
341 close_verifier(verifier);
342 nsd->verifier_count--;
343 }
344
345 while(nsd->mode == NSD_RUN0 &&
4
Assuming field 'mode' is equal to NSD_RUN
7
Loop condition is true. Entering loop body
346 nsd->verifier_count < nsd->verifier_limit &&
5
Assuming field 'verifier_count' is < field 'verifier_limit'
347 nsd->next_zone_to_verify != NULL((void *)0))
6
Assuming field 'next_zone_to_verify' is not equal to NULL
348 {
349 verify_zone(nsd, nsd->next_zone_to_verify);
8
Calling 'verify_zone'
350 nsd->next_zone_to_verify
351 = verify_next_zone(nsd, nsd->next_zone_to_verify);
352 }
353
354 if(nsd->next_zone_to_verify == NULL((void *)0) && nsd->verifier_count == 0) {
355 event_base_loopexit(nsd->event_base, NULL((void *)0));
356 return;
357 }
358}
359
360/*
361 * A parent may be terminated (by the NSD_QUIT signal (nsdc stop command)).
362 * When a reload server process is running, the parent will then send a
363 * NSD_QUIT command to that server. This handler makes sure that this command
364 * is not neglected and that the reload server process will exit (gracefully).
365 */
366void
367verify_handle_command(int fd, short event, void *arg)
368{
369 struct nsd *nsd = (struct nsd *)arg;
370 int len;
371 sig_atomic_t mode;
372
373 assert(nsd != NULL)((void)0);
374 assert(event & (EV_READ((void)0)
375#ifdef EV_CLOSED((void)0)
376 | EV_CLOSED((void)0)
377#endif((void)0)
378 ))((void)0);
379
380 if((len = read(fd, &mode, sizeof(mode))) == -1) {
381 log_msg(LOG_ERR3, "verify: verify_handle_command: read: %s",
382 strerror(errno(*__errno())));
383 return;
384 } else if(len == 0) {
385 log_msg(LOG_INFO6, "verify: command channel closed");
386 mode = NSD_QUIT5;
387 } else if(mode != NSD_QUIT5) {
388 log_msg(LOG_ERR3, "verify: bad command: %d", (int)mode);
389 return;
390 }
391
392 nsd->mode = mode;
393
394 if(nsd->verifier_count == 0) {
395 event_base_loopexit(nsd->event_base, NULL((void *)0));
396 return; /* exit early if no verifiers are executing */
397 }
398
399 /* kill verifiers, processes reaped elsewhere */
400 for(size_t i = 0; i < nsd->verifier_limit; i++) {
401 if(nsd->verifiers[i].zone != NULL((void *)0)) {
402 kill_verifier(&nsd->verifiers[i]);
403 }
404 }
405}
406
407/*
408 * A verifier is executed for the specified zone (if a verifier is configured
409 * and the zone has not been verified before). If one of the verifiers exits
410 * with non-zero, the zone is marked bad and nsd drops the zone update and
411 * reloads again.
412 */
413void verify_zone(struct nsd *nsd, struct zone *zone)
414{
415 struct verifier *verifier = NULL((void *)0);
9
'verifier' initialized to a null pointer value
416 int32_t timeout;
417 char **command;
418 FILE *fin;
419 int fdin, fderr, fdout, flags;
420
421 assert(nsd != NULL)((void)0);
422 assert(nsd->verifier_count < nsd->verifier_limit)((void)0);
423 assert(zone != NULL)((void)0);
424
425 fin = NULL((void *)0);
426 fdin = fdout = fderr = -1;
427
428 /* search for available verifier slot */
429 for(size_t i = 0; i < nsd->verifier_limit && !verifier; i++) {
10
Assuming 'i' is < field 'verifier_limit'
11
Loop condition is true. Entering loop body
14
Assuming 'i' is >= field 'verifier_limit'
430 if(nsd->verifiers[i].zone == NULL((void *)0)) {
12
Assuming field 'zone' is not equal to NULL
13
Taking false branch
431 verifier = &nsd->verifiers[i];
432 }
433 }
434
435 assert(verifier != NULL)((void)0);
436
437 if(zone->opts->pattern->verifier != NULL((void *)0)) {
15
Assuming field 'verifier' is not equal to NULL
16
Taking true branch
438 command = zone->opts->pattern->verifier;
439 } else if (nsd->options->verifier != NULL((void *)0)) {
440 command = nsd->options->verifier;
441 } else {
442 log_msg(LOG_ERR3, "verify: no verifier for zone %s",
443 zone->opts->name);
444 return;
445 }
446
447 if(zone->opts->pattern->verifier_timeout
17
Assuming the condition is false
18
Taking false branch
448 != VERIFIER_TIMEOUT_INHERIT(-1))
449 {
450 timeout = zone->opts->pattern->verifier_timeout;
451 } else {
452 timeout = nsd->options->verifier_timeout;
453 }
454
455 if(zone->opts->pattern->verifier_feed_zone
19
Assuming field 'verifier_feed_zone' is equal to VERIFIER_FEED_ZONE_INHERIT
456 != VERIFIER_FEED_ZONE_INHERIT(2))
457 {
458 fdin = zone->opts->pattern->verifier_feed_zone ? -2 : -1;
459 } else {
460 fdin = nsd->options->verifier_feed_zone ? -2 : -1;
20
Taking false branch
21
Assuming field 'verifier_feed_zone' is 0
22
'?' condition is false
461 }
462
463 assert(timeout >= 0)((void)0);
464
465 setenv("VERIFY_ZONE", zone->opts->name, 1);
466 setenv("VERIFY_ZONE_ON_STDIN", fdin == -2 ? "yes" : "no", 1);
23
'?' condition is false
467
468 verifier->pid = popen3(
25
Access to field 'pid' results in a dereference of a null pointer (loaded from variable 'verifier')
469 command, fdin == -2 ? &fdin : NULL((void *)0), &fdout, &fderr);
24
'?' condition is false
470 if(verifier->pid == -1) {
471 log_msg(LOG_ERR3, "verify: could not start verifier for zone "
472 "%s: %s", zone->opts->name, strerror(errno(*__errno())));
473 goto fail_popen3;
474 }
475 flags = fcntl(fderr, F_GETFL3, 0);
476 if (fcntl(fderr, F_SETFL4, flags | O_NONBLOCK0x0004) == -1) {
477 log_msg(LOG_ERR3, "verify: fcntl(stderr, ..., O_NONBLOCK) for "
478 "zone %s: %s",
479 zone->opts->name, strerror(errno(*__errno())));
480 goto fail_fcntl;
481 }
482 flags = fcntl(fdout, F_GETFL3, 0);
483 if(fcntl(fdout, F_SETFL4, flags | O_NONBLOCK0x0004) == -1) {
484 log_msg(LOG_ERR3, "verify: fcntl(stdout, ..., O_NONBLOCK) for "
485 "zone %s: %s",
486 zone->opts->name, strerror(errno(*__errno())));
487 goto fail_fcntl;
488 }
489 if (fdin >= 0) {
490 if ((fin = fdopen(fdin, "w")) == NULL((void *)0)) {
491 log_msg(LOG_ERR3, "verify: fdopen(stdin, ...) for "
492 "zone %s: %s",
493 zone->opts->name, strerror(errno(*__errno())));
494 goto fail_fcntl;
495 }
496 /* write unbuffered */
497 setbuf(fin, NULL((void *)0));
498 }
499
500 verifier->zone = zone;
501 verifier->was_ok = zone->is_ok;
502
503 unsetenv("VERIFY_ZONE");
504 unsetenv("VERIFY_ZONE_ON_STDIN");
505
506 verifier->error_stream.fd = fderr;
507 verifier->error_stream.cnt = 0;
508 verifier->error_stream.off = 0;
509 verifier->error_stream.buf[0] = '\0';
510 event_set(&verifier->error_stream.event,
511 verifier->error_stream.fd,
512 EV_READ0x02|EV_PERSIST0x10,
513 verify_handle_stream,
514 verifier);
515 event_base_set(nsd->event_base, &verifier->error_stream.event);
516 if(event_add(&verifier->error_stream.event, NULL((void *)0)) != 0) {
517 log_msg(LOG_ERR3, "verify: could not add error event for "
518 "zone %s", zone->opts->name);
519 goto fail_stderr;
520 }
521
522 verifier->output_stream.fd = fdout;
523 verifier->output_stream.cnt = 0;
524 verifier->output_stream.off = 0;
525 verifier->output_stream.buf[0] = '\0';
526 event_set(&verifier->output_stream.event,
527 verifier->output_stream.fd,
528 EV_READ0x02|EV_PERSIST0x10,
529 verify_handle_stream,
530 verifier);
531 event_base_set(nsd->event_base, &verifier->output_stream.event);
532 if(event_add(&verifier->output_stream.event, NULL((void *)0)) != 0) {
533 log_msg(LOG_ERR3, "verify: could not add output event for "
534 "zone %s", zone->opts->name);
535 goto fail_stdout;
536 }
537
538 if(fin != NULL((void *)0)) {
539 verifier->zone_feed.fh = fin;
540
541 zone_rr_iter_init(&verifier->zone_feed.rriter, zone);
542
543 verifier->zone_feed.rrprinter
544 = create_pretty_rr(nsd->server_region);
545 verifier->zone_feed.region
546 = region_create(xalloc, free);
547 verifier->zone_feed.buffer
548 = buffer_create(nsd->server_region, MAX_RDLENGTH65535);
549
550 event_set(&verifier->zone_feed.event,
551 fileno(verifier->zone_feed.fh)(!__isthreaded ? ((verifier->zone_feed.fh)->_file) : (fileno
)(verifier->zone_feed.fh))
,
552 EV_WRITE0x04|EV_PERSIST0x10,
553 &verify_handle_feed,
554 verifier);
555 event_base_set(nsd->event_base, &verifier->zone_feed.event);
556 if(event_add(&verifier->zone_feed.event, NULL((void *)0)) != 0) {
557 log_msg(LOG_ERR3, "verify: could not add input event "
558 "for zone %s", zone->opts->name);
559 goto fail_stdin;
560 }
561 }
562
563 if(timeout > 0) {
564 verifier->timeout.tv_sec = timeout;
565 verifier->timeout.tv_usec = 0;
566 event_set(&verifier->timeout_event,
567 -1,
568 EV_TIMEOUT0x01,
569 verify_handle_timeout,
570 verifier);
571 event_base_set(nsd->event_base, &verifier->timeout_event);
572 if(event_add(&verifier->timeout_event, &verifier->timeout) != 0) {
573 log_msg(LOG_ERR3, "verify: could not add timeout event "
574 "for zone %s", zone->opts->name);
575 goto fail_timeout;
576 }
577
578 log_msg(LOG_INFO6, "verify: started verifier for zone %s "
579 "(pid %d), timeout is %d seconds",
580 zone->opts->name, verifier->pid, timeout);
581 } else {
582 log_msg(LOG_INFO6, "verify: started verifier for zone %s "
583 "(pid %d)", zone->opts->name, verifier->pid);
584 }
585
586 zone->is_ok = 1;
587 nsd->verifier_count++;
588 return;
589
590fail_timeout:
591 verifier->timeout.tv_sec = 0;
592 verifier->timeout.tv_usec = 0;
593 if(fin != NULL((void *)0)) {
594 event_del(&verifier->zone_feed.event);
595 }
596fail_stdin:
597 verifier->zone_feed.fh = NULL((void *)0);
598 event_del(&verifier->output_stream.event);
599fail_stdout:
600 verifier->output_stream.fd = -1;
601 event_del(&verifier->error_stream.event);
602fail_stderr:
603 verifier->error_stream.fd = -1;
604fail_fcntl:
605 kill_verifier(verifier);
606 if(fin != NULL((void *)0)) {
607 fclose(fin);
608 } else if (fdin >= 0) {
609 close(fdin);
610 }
611 close(fdout);
612 close(fderr);
613fail_popen3:
614 zone->is_bad = 1;
615 verifier->pid = -1;
616 verifier->zone = NULL((void *)0);
617}