Bug Summary

File:src/sbin/dhcpleased/obj/parse.c
Warning:line 1213, column 10
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 parse.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/sbin/dhcpleased/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sbin/dhcpleased -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/sbin/dhcpleased/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 parse.c
1#include <stdlib.h>
2#include <string.h>
3#define YYBYACC1 1
4#define YYMAJOR1 1
5#define YYMINOR9 9
6#define YYLEXyylex() yylex()
7#define YYEMPTY-1 -1
8#define yyclearin(yychar=(-1)) (yychar=(YYEMPTY-1))
9#define yyerrok(yyerrflag=0) (yyerrflag=0)
10#define YYRECOVERING()(yyerrflag!=0) (yyerrflag!=0)
11#define YYPREFIX"yy" "yy"
12#line 26 "/usr/src/sbin/dhcpleased/parse.y"
13#include <sys/types.h>
14#include <sys/queue.h>
15#include <sys/socket.h>
16#include <sys/stat.h>
17
18#include <net/if.h>
19
20#include <netinet/in.h>
21#include <netinet/if_ether.h>
22
23#include <arpa/inet.h>
24
25#include <ctype.h>
26#include <err.h>
27#include <errno(*__errno()).h>
28#include <event.h>
29#include <imsg.h>
30#include <limits.h>
31#include <stdarg.h>
32#include <stdio.h>
33#include <string.h>
34#include <syslog.h>
35#include <unistd.h>
36#include <vis.h>
37
38#include "log.h"
39#include "dhcpleased.h"
40#include "frontend.h"
41
42TAILQ_HEAD(files, file)struct files { struct file *tqh_first; struct file **tqh_last
; }
files = TAILQ_HEAD_INITIALIZER(files){ ((void *)0), &(files).tqh_first };
43static struct file {
44 TAILQ_ENTRY(file)struct { struct file *tqe_next; struct file **tqe_prev; } entry;
45 FILE *stream;
46 char *name;
47 size_t ungetpos;
48 size_t ungetsize;
49 u_char *ungetbuf;
50 int eof_reached;
51 int lineno;
52 int errors;
53} *file, *topfile;
54struct file *pushfile(const char *, int);
55int popfile(void);
56int check_file_secrecy(int, const char *);
57int yyparse(void);
58int yylex(void);
59int yyerror(const char *, ...)
60 __attribute__((__format__ (printf, 1, 2)))
61 __attribute__((__nonnull__ (1)));
62int kw_cmp(const void *, const void *);
63int lookup(char *);
64int igetc(void);
65int lgetc(int);
66void lungetc(int);
67int findeol(void);
68
69TAILQ_HEAD(symhead, sym)struct symhead { struct sym *tqh_first; struct sym **tqh_last
; }
symhead = TAILQ_HEAD_INITIALIZER(symhead){ ((void *)0), &(symhead).tqh_first };
70struct sym {
71 TAILQ_ENTRY(sym)struct { struct sym *tqe_next; struct sym **tqe_prev; } entry;
72 int used;
73 int persist;
74 char *nam;
75 char *val;
76};
77
78int symset(const char *, const char *, int);
79char *symget(const char *);
80
81static struct dhcpleased_conf *conf;
82static int errors;
83
84static struct iface_conf *iface_conf;
85
86struct iface_conf *conf_get_iface(char *);
87
88typedef struct {
89 union {
90 int64_t number;
91 char *string;
92 } v;
93 int lineno;
94} YYSTYPE;
95
96#line 97 "parse.c"
97#define DHCP_IFACE257 257
98#define ERROR258 258
99#define SEND259 259
100#define VENDOR260 260
101#define CLASS261 261
102#define ID262 262
103#define CLIENT263 263
104#define IGNORE264 264
105#define DNS265 265
106#define ROUTES266 266
107#define HOST267 267
108#define NAME268 268
109#define NO269 269
110#define STRING270 270
111#define NUMBER271 271
112#define YYERRCODE256 256
113const short yylhs[] =
114 { -1,
115 0, 0, 0, 0, 0, 1, 1, 2, 4, 4,
116 5, 6, 3, 7, 7, 8, 8, 9, 9, 9,
117 9, 9, 9, 9,
118};
119const short yylen[] =
120 { 2,
121 0, 2, 3, 3, 3, 2, 1, 3, 2, 0,
122 2, 0, 6, 2, 1, 3, 2, 5, 4, 4,
123 4, 2, 2, 2,
124};
125const short yydefred[] =
126 { 1,
127 0, 0, 0, 0, 2, 0, 0, 5, 12, 0,
128 3, 4, 0, 7, 0, 0, 6, 0, 0, 0,
129 9, 0, 0, 0, 0, 13, 0, 0, 0, 0,
130 23, 22, 24, 0, 17, 0, 0, 0, 0, 0,
131 16, 0, 19, 20, 21, 11, 18,
132};
133const short yydgoto[] =
134 { 1,
135 15, 6, 7, 19, 41, 13, 20, 24, 25,
136};
137const short yysindex[] =
138 { 0,
139 -10, -6, -265, -54, 0, -2, 5, 0, 0, -253,
140 0, 0, -104, 0, -250, 11, 0, 11, -248, -103,
141 0, -257, -252, -248, 11, 0, -238, -237, -242, -240,
142 0, 0, 0, 18, 0, -233, -239, -236, -235, 11,
143 0, -234, 0, 0, 0, 0, 0,};
144const short yyrindex[] =
145 { 0,
146 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
147 0, 0, 0, 0, -6, -124, 0, -124, -95, 0,
148 0, 0, 0, -93, -124, 0, 0, 0, 0, 0,
149 0, 0, 0, 0, 0, 0, 0, 0, 0, -124,
150 0, 0, 0, 0, 0, 0, 0,};
151const short yygindex[] =
152 { 0,
153 0, 0, 0, -16, 0, 0, 0, 0, 13,
154};
155#define YYTABLESIZE260 260
156const short yytable[] =
157 { 5,
158 10, 21, 27, 8, 9, 28, 10, 11, 35, 29,
159 22, 30, 31, 32, 12, 23, 14, 33, 16, 17,
160 18, 26, 36, 46, 37, 38, 39, 40, 42, 15,
161 43, 14, 45, 44, 0, 47, 34, 0, 0, 0,
162 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
163 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
164 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
165 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
166 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
167 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
168 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
169 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
170 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
171 0, 0, 0, 0, 10, 0, 0, 0, 0, 10,
172 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
173 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
174 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
175 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
176 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
177 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
178 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
179 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
180 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
181 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
182 0, 0, 0, 0, 0, 2, 3, 0, 0, 0,
183 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
184};
185const short yycheck[] =
186 { 10,
187 125, 18, 260, 10, 270, 263, 61, 10, 25, 267,
188 259, 269, 265, 266, 10, 264, 270, 270, 123, 270,
189 10, 125, 261, 40, 262, 268, 267, 10, 262, 125,
190 270, 125, 268, 270, -1, 270, 24, -1, -1, -1,
191 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
192 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
193 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
194 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
195 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
196 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
197 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
198 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
199 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
200 -1, -1, -1, -1, 259, -1, -1, -1, -1, 264,
201 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
202 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
203 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
204 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
205 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
206 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
207 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
208 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
209 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
210 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
211 -1, -1, -1, -1, -1, 256, 257, -1, -1, -1,
212 -1, -1, -1, -1, -1, -1, -1, -1, -1, 270,
213};
214#define YYFINAL1 1
215#ifndef YYDEBUG0
216#define YYDEBUG0 0
217#endif
218#define YYMAXTOKEN271 271
219#if YYDEBUG0
220const char * const yyname[] =
221 {
222"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'='",0,0,0,0,0,0,0,
2240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2250,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2280,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"DHCP_IFACE",
229"ERROR","SEND","VENDOR","CLASS","ID","CLIENT","IGNORE","DNS","ROUTES","HOST",
230"NAME","NO","STRING","NUMBER",
231};
232const char * const yyrule[] =
233 {"$accept : grammar",
234"grammar :",
235"grammar : grammar '\\n'",
236"grammar : grammar varset '\\n'",
237"grammar : grammar dhcp_iface '\\n'",
238"grammar : grammar error '\\n'",
239"string : string STRING",
240"string : STRING",
241"varset : STRING '=' string",
242"optnl : '\\n' optnl",
243"optnl :",
244"nl : '\\n' optnl",
245"$$1 :",
246"dhcp_iface : DHCP_IFACE STRING $$1 '{' iface_block '}'",
247"iface_block : optnl ifaceopts_l",
248"iface_block : optnl",
249"ifaceopts_l : ifaceopts_l ifaceoptsl nl",
250"ifaceopts_l : ifaceoptsl optnl",
251"ifaceoptsl : SEND VENDOR CLASS ID STRING",
252"ifaceoptsl : SEND CLIENT ID STRING",
253"ifaceoptsl : SEND HOST NAME STRING",
254"ifaceoptsl : SEND NO HOST NAME",
255"ifaceoptsl : IGNORE ROUTES",
256"ifaceoptsl : IGNORE DNS",
257"ifaceoptsl : IGNORE STRING",
258};
259#endif
260#ifdef YYSTACKSIZE10000
261#undef YYMAXDEPTH10000
262#define YYMAXDEPTH10000 YYSTACKSIZE10000
263#else
264#ifdef YYMAXDEPTH10000
265#define YYSTACKSIZE10000 YYMAXDEPTH10000
266#else
267#define YYSTACKSIZE10000 10000
268#define YYMAXDEPTH10000 10000
269#endif
270#endif
271#define YYINITSTACKSIZE200 200
272/* LINTUSED */
273int yydebug;
274int yynerrs;
275int yyerrflag;
276int yychar;
277short *yyssp;
278YYSTYPE *yyvsp;
279YYSTYPE yyval;
280YYSTYPE yylval;
281short *yyss;
282short *yysslim;
283YYSTYPE *yyvs;
284unsigned int yystacksize;
285int yyparse(void);
286#line 329 "/usr/src/sbin/dhcpleased/parse.y"
287
288struct keywords {
289 const char *k_name;
290 int k_val;
291};
292
293int
294yyerror(const char *fmt, ...)
295{
296 va_list ap;
297 char *msg;
298
299 file->errors++;
300 va_start(ap, fmt)__builtin_va_start(ap, fmt);
301 if (vasprintf(&msg, fmt, ap) == -1)
302 fatalx("yyerror vasprintf");
303 va_end(ap)__builtin_va_end(ap);
304 logit(LOG_CRIT2, "%s:%d: %s", file->name, yylval.lineno, msg);
305 free(msg);
306 return (0);
307}
308
309int
310kw_cmp(const void *k, const void *e)
311{
312 return (strcmp(k, ((const struct keywords *)e)->k_name));
313}
314
315int
316lookup(char *s)
317{
318 /* This has to be sorted always. */
319 static const struct keywords keywords[] = {
320 {"class", CLASS261},
321 {"client", CLIENT263},
322 {"dns", DNS265},
323 {"host", HOST267},
324 {"id", ID262},
325 {"ignore", IGNORE264},
326 {"interface", DHCP_IFACE257},
327 {"name", NAME268},
328 {"no", NO269},
329 {"routes", ROUTES266},
330 {"send", SEND259},
331 {"vendor", VENDOR260},
332 };
333 const struct keywords *p;
334
335 p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
336 sizeof(keywords[0]), kw_cmp);
337
338 if (p)
339 return (p->k_val);
340 else
341 return (STRING270);
342}
343
344#define START_EXPAND1 1
345#define DONE_EXPAND2 2
346
347static int expanding;
348
349int
350igetc(void)
351{
352 int c;
353
354 while (1) {
355 if (file->ungetpos > 0)
356 c = file->ungetbuf[--file->ungetpos];
357 else
358 c = getc(file->stream)(!__isthreaded ? (--(file->stream)->_r < 0 ? __srget
(file->stream) : (int)(*(file->stream)->_p++)) : (getc
)(file->stream))
;
359
360 if (c == START_EXPAND1)
361 expanding = 1;
362 else if (c == DONE_EXPAND2)
363 expanding = 0;
364 else
365 break;
366 }
367 return (c);
368}
369
370int
371lgetc(int quotec)
372{
373 int c, next;
374
375 if (quotec) {
376 if ((c = igetc()) == EOF(-1)) {
377 yyerror("reached end of file while parsing "
378 "quoted string");
379 if (file == topfile || popfile() == EOF(-1))
380 return (EOF(-1));
381 return (quotec);
382 }
383 return (c);
384 }
385
386 while ((c = igetc()) == '\\') {
387 next = igetc();
388 if (next != '\n') {
389 c = next;
390 break;
391 }
392 yylval.lineno = file->lineno;
393 file->lineno++;
394 }
395
396 if (c == EOF(-1)) {
397 /*
398 * Fake EOL when hit EOF for the first time. This gets line
399 * count right if last line in included file is syntactically
400 * invalid and has no newline.
401 */
402 if (file->eof_reached == 0) {
403 file->eof_reached = 1;
404 return ('\n');
405 }
406 while (c == EOF(-1)) {
407 if (file == topfile || popfile() == EOF(-1))
408 return (EOF(-1));
409 c = igetc();
410 }
411 }
412 return (c);
413}
414
415void
416lungetc(int c)
417{
418 if (c == EOF(-1))
419 return;
420
421 if (file->ungetpos >= file->ungetsize) {
422 void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
423 if (p == NULL((void *)0))
424 err(1, "lungetc");
425 file->ungetbuf = p;
426 file->ungetsize *= 2;
427 }
428 file->ungetbuf[file->ungetpos++] = c;
429}
430
431int
432findeol(void)
433{
434 int c;
435
436 /* Skip to either EOF or the first real EOL. */
437 while (1) {
438 c = lgetc(0);
439 if (c == '\n') {
440 file->lineno++;
441 break;
442 }
443 if (c == EOF(-1))
444 break;
445 }
446 return (ERROR258);
447}
448
449int
450yylex(void)
451{
452 char buf[8096];
453 char *p, *val;
454 int quotec, next, c;
455 int token;
456
457top:
458 p = buf;
459 while ((c = lgetc(0)) == ' ' || c == '\t')
460 ; /* nothing */
461
462 yylval.lineno = file->lineno;
463 if (c == '#')
464 while ((c = lgetc(0)) != '\n' && c != EOF(-1))
465 ; /* nothing */
466 if (c == '$' && !expanding) {
467 while (1) {
468 if ((c = lgetc(0)) == EOF(-1))
469 return (0);
470
471 if (p + 1 >= buf + sizeof(buf) - 1) {
472 yyerror("string too long");
473 return (findeol());
474 }
475 if (isalnum(c) || c == '_') {
476 *p++ = c;
477 continue;
478 }
479 *p = '\0';
480 lungetc(c);
481 break;
482 }
483 val = symget(buf);
484 if (val == NULL((void *)0)) {
485 yyerror("macro '%s' not defined", buf);
486 return (findeol());
487 }
488 p = val + strlen(val) - 1;
489 lungetc(DONE_EXPAND2);
490 while (p >= val) {
491 lungetc((unsigned char)*p);
492 p--;
493 }
494 lungetc(START_EXPAND1);
495 goto top;
496 }
497
498 switch (c) {
499 case '\'':
500 case '"':
501 quotec = c;
502 while (1) {
503 if ((c = lgetc(quotec)) == EOF(-1))
504 return (0);
505 if (c == '\n') {
506 file->lineno++;
507 continue;
508 } else if (c == '\\') {
509 if ((next = lgetc(quotec)) == EOF(-1))
510 return (0);
511 if (next == quotec || next == ' ' ||
512 next == '\t')
513 c = next;
514 else if (next == '\n') {
515 file->lineno++;
516 continue;
517 } else
518 lungetc(next);
519 } else if (c == quotec) {
520 *p = '\0';
521 break;
522 } else if (c == '\0') {
523 yyerror("syntax error");
524 return (findeol());
525 }
526 if (p + 1 >= buf + sizeof(buf) - 1) {
527 yyerror("string too long");
528 return (findeol());
529 }
530 *p++ = c;
531 }
532 yylval.v.string = strdup(buf);
533 if (yylval.v.string == NULL((void *)0))
534 err(1, "yylex: strdup");
535 return (STRING270);
536 }
537
538#define allowed_to_end_number(x)(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' ||
x == '=')
\
539 (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
540
541 if (c == '-' || isdigit(c)) {
542 do {
543 *p++ = c;
544 if ((size_t)(p-buf) >= sizeof(buf)) {
545 yyerror("string too long");
546 return (findeol());
547 }
548 } while ((c = lgetc(0)) != EOF(-1) && isdigit(c));
549 lungetc(c);
550 if (p == buf + 1 && buf[0] == '-')
551 goto nodigits;
552 if (c == EOF(-1) || allowed_to_end_number(c)(isspace(c) || c == ')' || c ==',' || c == '/' || c == '}' ||
c == '=')
) {
553 const char *errstr = NULL((void *)0);
554
555 *p = '\0';
556 yylval.v.number = strtonum(buf, LLONG_MIN(-9223372036854775807LL -1LL),
557 LLONG_MAX9223372036854775807LL, &errstr);
558 if (errstr) {
559 yyerror("\"%s\" invalid number: %s",
560 buf, errstr);
561 return (findeol());
562 }
563 return (NUMBER271);
564 } else {
565nodigits:
566 while (p > buf + 1)
567 lungetc((unsigned char)*--p);
568 c = (unsigned char)*--p;
569 if (c == '-')
570 return (c);
571 }
572 }
573
574#define allowed_in_string(x)(isalnum(x) || (ispunct(x) && x != '(' && x !=
')' && x != '{' && x != '}' && x != '!'
&& x != '=' && x != '#' && x != ',')
)
\
575 (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
576 x != '{' && x != '}' && \
577 x != '!' && x != '=' && x != '#' && \
578 x != ','))
579
580 if (isalnum(c) || c == ':' || c == '_') {
581 do {
582 *p++ = c;
583 if ((size_t)(p-buf) >= sizeof(buf)) {
584 yyerror("string too long");
585 return (findeol());
586 }
587 } while ((c = lgetc(0)) != EOF(-1) && (allowed_in_string(c)(isalnum(c) || (ispunct(c) && c != '(' && c !=
')' && c != '{' && c != '}' && c != '!'
&& c != '=' && c != '#' && c != ',')
)
));
588 lungetc(c);
589 *p = '\0';
590 if ((token = lookup(buf)) == STRING270)
591 if ((yylval.v.string = strdup(buf)) == NULL((void *)0))
592 err(1, "yylex: strdup");
593 return (token);
594 }
595 if (c == '\n') {
596 yylval.lineno = file->lineno;
597 file->lineno++;
598 }
599 if (c == EOF(-1))
600 return (0);
601 return (c);
602}
603
604int
605check_file_secrecy(int fd, const char *fname)
606{
607 struct stat st;
608
609 if (fstat(fd, &st)) {
610 log_warn("cannot stat %s", fname);
611 return (-1);
612 }
613 if (st.st_uid != 0 && st.st_uid != getuid()) {
614 log_warnx("%s: owner not root or current user", fname);
615 return (-1);
616 }
617 if (st.st_mode & (S_IWGRP0000020 | S_IXGRP0000010 | S_IRWXO0000007)) {
618 log_warnx("%s: group writable or world read/writable", fname);
619 return (-1);
620 }
621 return (0);
622}
623
624struct file *
625pushfile(const char *name, int secret)
626{
627 struct file *nfile;
628
629 if ((nfile = calloc(1, sizeof(struct file))) == NULL((void *)0)) {
630 log_warn("calloc");
631 return (NULL((void *)0));
632 }
633 if ((nfile->name = strdup(name)) == NULL((void *)0)) {
634 log_warn("strdup");
635 free(nfile);
636 return (NULL((void *)0));
637 }
638 if ((nfile->stream = fopen(nfile->name, "r")) == NULL((void *)0)) {
639 free(nfile->name);
640 free(nfile);
641 return (NULL((void *)0));
642 } else if (secret &&
643 check_file_secrecy(fileno(nfile->stream)(!__isthreaded ? ((nfile->stream)->_file) : (fileno)(nfile
->stream))
, nfile->name)) {
644 fclose(nfile->stream);
645 free(nfile->name);
646 free(nfile);
647 return (NULL((void *)0));
648 }
649 nfile->lineno = TAILQ_EMPTY(&files)(((&files)->tqh_first) == ((void *)0)) ? 1 : 0;
650 nfile->ungetsize = 16;
651 nfile->ungetbuf = malloc(nfile->ungetsize);
652 if (nfile->ungetbuf == NULL((void *)0)) {
653 log_warn("malloc");
654 fclose(nfile->stream);
655 free(nfile->name);
656 free(nfile);
657 return (NULL((void *)0));
658 }
659 TAILQ_INSERT_TAIL(&files, nfile, entry)do { (nfile)->entry.tqe_next = ((void *)0); (nfile)->entry
.tqe_prev = (&files)->tqh_last; *(&files)->tqh_last
= (nfile); (&files)->tqh_last = &(nfile)->entry
.tqe_next; } while (0)
;
660 return (nfile);
661}
662
663int
664popfile(void)
665{
666 struct file *prev;
667
668 if ((prev = TAILQ_PREV(file, files, entry)(*(((struct files *)((file)->entry.tqe_prev))->tqh_last
))
) != NULL((void *)0))
669 prev->errors += file->errors;
670
671 TAILQ_REMOVE(&files, file, entry)do { if (((file)->entry.tqe_next) != ((void *)0)) (file)->
entry.tqe_next->entry.tqe_prev = (file)->entry.tqe_prev
; else (&files)->tqh_last = (file)->entry.tqe_prev;
*(file)->entry.tqe_prev = (file)->entry.tqe_next; ; ; }
while (0)
;
672 fclose(file->stream);
673 free(file->name);
674 free(file->ungetbuf);
675 free(file);
676 file = prev;
677 return (file ? 0 : EOF(-1));
678}
679
680struct dhcpleased_conf *
681parse_config(char *filename)
682{
683 struct sym *sym, *next;
684
685 conf = config_new_empty();
686
687 file = pushfile(filename != NULL((void *)0) ? filename : _PATH_CONF_FILE"/etc/dhcpleased.conf", 0);
688 if (file == NULL((void *)0)) {
689 /* no default config file is fine */
690 if (errno(*__errno()) == ENOENT2 && filename == NULL((void *)0))
691 return (conf);
692 log_warn("%s", filename);
693 free(conf);
694 return (NULL((void *)0));
695 }
696 topfile = file;
697
698 yyparse();
699 errors = file->errors;
700 popfile();
701
702 /* Free macros and check which have not been used. */
703 TAILQ_FOREACH_SAFE(sym, &symhead, entry, next)for ((sym) = ((&symhead)->tqh_first); (sym) != ((void *
)0) && ((next) = ((sym)->entry.tqe_next), 1); (sym
) = (next))
{
704 if ((log_getverbose() == 2) && !sym->used)
705 fprintf(stderr(&__sF[2]), "warning: macro '%s' not used\n",
706 sym->nam);
707 if (!sym->persist) {
708 free(sym->nam);
709 free(sym->val);
710 TAILQ_REMOVE(&symhead, sym, entry)do { if (((sym)->entry.tqe_next) != ((void *)0)) (sym)->
entry.tqe_next->entry.tqe_prev = (sym)->entry.tqe_prev;
else (&symhead)->tqh_last = (sym)->entry.tqe_prev;
*(sym)->entry.tqe_prev = (sym)->entry.tqe_next; ; ; } while
(0)
;
711 free(sym);
712 }
713 }
714
715 if (errors) {
716 config_clear(conf);
717 return (NULL((void *)0));
718 }
719
720 return (conf);
721}
722
723int
724symset(const char *nam, const char *val, int persist)
725{
726 struct sym *sym;
727
728 TAILQ_FOREACH(sym, &symhead, entry)for((sym) = ((&symhead)->tqh_first); (sym) != ((void *
)0); (sym) = ((sym)->entry.tqe_next))
{
729 if (strcmp(nam, sym->nam) == 0)
730 break;
731 }
732
733 if (sym != NULL((void *)0)) {
734 if (sym->persist == 1)
735 return (0);
736 else {
737 free(sym->nam);
738 free(sym->val);
739 TAILQ_REMOVE(&symhead, sym, entry)do { if (((sym)->entry.tqe_next) != ((void *)0)) (sym)->
entry.tqe_next->entry.tqe_prev = (sym)->entry.tqe_prev;
else (&symhead)->tqh_last = (sym)->entry.tqe_prev;
*(sym)->entry.tqe_prev = (sym)->entry.tqe_next; ; ; } while
(0)
;
740 free(sym);
741 }
742 }
743 if ((sym = calloc(1, sizeof(*sym))) == NULL((void *)0))
744 return (-1);
745
746 sym->nam = strdup(nam);
747 if (sym->nam == NULL((void *)0)) {
748 free(sym);
749 return (-1);
750 }
751 sym->val = strdup(val);
752 if (sym->val == NULL((void *)0)) {
753 free(sym->nam);
754 free(sym);
755 return (-1);
756 }
757 sym->used = 0;
758 sym->persist = persist;
759 TAILQ_INSERT_TAIL(&symhead, sym, entry)do { (sym)->entry.tqe_next = ((void *)0); (sym)->entry.
tqe_prev = (&symhead)->tqh_last; *(&symhead)->tqh_last
= (sym); (&symhead)->tqh_last = &(sym)->entry.
tqe_next; } while (0)
;
760 return (0);
761}
762
763int
764cmdline_symset(char *s)
765{
766 char *sym, *val;
767 int ret;
768
769 if ((val = strrchr(s, '=')) == NULL((void *)0))
770 return (-1);
771 sym = strndup(s, val - s);
772 if (sym == NULL((void *)0))
773 errx(1, "%s: strndup", __func__);
774 ret = symset(sym, val + 1, 1);
775 free(sym);
776
777 return (ret);
778}
779
780char *
781symget(const char *nam)
782{
783 struct sym *sym;
784
785 TAILQ_FOREACH(sym, &symhead, entry)for((sym) = ((&symhead)->tqh_first); (sym) != ((void *
)0); (sym) = ((sym)->entry.tqe_next))
{
786 if (strcmp(nam, sym->nam) == 0) {
787 sym->used = 1;
788 return (sym->val);
789 }
790 }
791 return (NULL((void *)0));
792}
793
794struct iface_conf *
795conf_get_iface(char *name)
796{
797 struct iface_conf *iface;
798 size_t n;
799
800 SIMPLEQ_FOREACH(iface, &conf->iface_list, entry)for((iface) = ((&conf->iface_list)->sqh_first); (iface
) != ((void *)0); (iface) = ((iface)->entry.sqe_next))
{
801 if (strcmp(name, iface->name) == 0)
802 return (iface);
803 }
804
805 iface = calloc(1, sizeof(*iface));
806 if (iface == NULL((void *)0))
807 errx(1, "%s: calloc", __func__);
808 n = strlcpy(iface->name, name, sizeof(iface->name));
809 if (n >= sizeof(iface->name))
810 errx(1, "%s: name too long", __func__);
811
812
813 SIMPLEQ_INSERT_TAIL(&conf->iface_list, iface, entry)do { (iface)->entry.sqe_next = ((void *)0); *(&conf->
iface_list)->sqh_last = (iface); (&conf->iface_list
)->sqh_last = &(iface)->entry.sqe_next; } while (0)
;
814
815 return (iface);
816}
817#line 810 "parse.c"
818/* allocate initial stack or double stack size, up to YYMAXDEPTH */
819static int yygrowstack(void)
820{
821 unsigned int newsize;
822 long sslen;
823 short *newss;
824 YYSTYPE *newvs;
825
826 if ((newsize = yystacksize) == 0)
827 newsize = YYINITSTACKSIZE200;
828 else if (newsize >= YYMAXDEPTH10000)
829 return -1;
830 else if ((newsize *= 2) > YYMAXDEPTH10000)
831 newsize = YYMAXDEPTH10000;
832 sslen = yyssp - yyss;
833#ifdef SIZE_MAX0xffffffffffffffffUL
834#define YY_SIZE_MAX0xffffffffffffffffUL SIZE_MAX0xffffffffffffffffUL
835#else
836#define YY_SIZE_MAX0xffffffffffffffffUL 0xffffffffU
837#endif
838 if (newsize && YY_SIZE_MAX0xffffffffffffffffUL / newsize < sizeof *newss)
839 goto bail;
840 newss = (short *)realloc(yyss, newsize * sizeof *newss);
841 if (newss == NULL((void *)0))
842 goto bail;
843 yyss = newss;
844 yyssp = newss + sslen;
845 if (newsize && YY_SIZE_MAX0xffffffffffffffffUL / newsize < sizeof *newvs)
846 goto bail;
847 newvs = (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs);
848 if (newvs == NULL((void *)0))
849 goto bail;
850 yyvs = newvs;
851 yyvsp = newvs + sslen;
852 yystacksize = newsize;
853 yysslim = yyss + newsize - 1;
854 return 0;
855bail:
856 if (yyss)
857 free(yyss);
858 if (yyvs)
859 free(yyvs);
860 yyss = yyssp = NULL((void *)0);
861 yyvs = yyvsp = NULL((void *)0);
862 yystacksize = 0;
863 return -1;
864}
865
866#define YYABORTgoto yyabort goto yyabort
867#define YYREJECTgoto yyabort goto yyabort
868#define YYACCEPTgoto yyaccept goto yyaccept
869#define YYERRORgoto yyerrlab goto yyerrlab
870int
871yyparse(void)
872{
873 int yym, yyn, yystate;
874#if YYDEBUG0
875 const char *yys;
876
877 if ((yys = getenv("YYDEBUG")))
878 {
879 yyn = *yys;
880 if (yyn >= '0' && yyn <= '9')
881 yydebug = yyn - '0';
882 }
883#endif /* YYDEBUG */
884
885 yynerrs = 0;
886 yyerrflag = 0;
887 yychar = (-1);
888
889 if (yyss == NULL((void *)0) && yygrowstack()) goto yyoverflow;
1
Assuming 'yyss' is not equal to NULL
890 yyssp = yyss;
891 yyvsp = yyvs;
892 *yyssp = yystate = 0;
893
894yyloop:
895 if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
2
Taking true branch
3
Control jumps to line 1002
13
Taking false branch
31
Assuming the condition is true
32
Taking true branch
33
Control jumps to line 1002
46
Assuming the condition is true
47
Taking true branch
48
Control jumps to line 1002
896 if (yychar
13.1
'yychar' is >= 0
< 0)
14
Taking false branch
897 {
898 if ((yychar = yylex()) < 0) yychar = 0;
899#if YYDEBUG0
900 if (yydebug)
901 {
902 yys = 0;
903 if (yychar <= YYMAXTOKEN271) yys = yyname[yychar];
904 if (!yys) yys = "illegal-symbol";
905 printf("%sdebug: state %d, reading %d (%s)\n",
906 YYPREFIX"yy", yystate, yychar, yys);
907 }
908#endif
909 }
910 if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
15
Assuming 'yyn' is not equal to 0
16
Assuming the condition is false
911 yyn <= YYTABLESIZE260 && yycheck[yyn] == yychar)
912 {
913#if YYDEBUG0
914 if (yydebug)
915 printf("%sdebug: state %d, shifting to state %d\n",
916 YYPREFIX"yy", yystate, yytable[yyn]);
917#endif
918 if (yyssp >= yysslim && yygrowstack())
919 {
920 goto yyoverflow;
921 }
922 *++yyssp = yystate = yytable[yyn];
923 *++yyvsp = yylval;
924 yychar = (-1);
925 if (yyerrflag > 0) --yyerrflag;
926 goto yyloop;
927 }
928 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
17
Assuming 'yyn' is 0
929 yyn <= YYTABLESIZE260 && yycheck[yyn] == yychar)
930 {
931 yyn = yytable[yyn];
932 goto yyreduce;
933 }
934 if (yyerrflag) goto yyinrecovery;
18
Assuming 'yyerrflag' is not equal to 0
19
Taking true branch
20
Control jumps to line 946
935#if defined(__GNUC__4)
936 goto yynewerror;
937#endif
938yynewerror:
939 yyerror("syntax error");
940#if defined(__GNUC__4)
941 goto yyerrlab;
942#endif
943yyerrlab:
944 ++yynerrs;
945yyinrecovery:
946 if (yyerrflag < 3)
21
Assuming 'yyerrflag' is < 3
22
Taking true branch
41
Assuming 'yyerrflag' is >= 3
42
Taking false branch
947 {
948 yyerrflag = 3;
949 for (;;)
23
Loop condition is true. Entering loop body
950 {
951 if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE256) >= 0 &&
24
Assuming 'yyn' is not equal to 0
25
Assuming the condition is true
28
Taking true branch
952 yyn <= YYTABLESIZE260 && yycheck[yyn] == YYERRCODE256)
26
Assuming 'yyn' is <= YYTABLESIZE
27
Assuming the condition is true
953 {
954#if YYDEBUG0
955 if (yydebug)
956 printf("%sdebug: state %d, error recovery shifting\
957 to state %d\n", YYPREFIX"yy", *yyssp, yytable[yyn]);
958#endif
959 if (yyssp >= yysslim && yygrowstack())
29
Assuming 'yyssp' is < 'yysslim'
960 {
961 goto yyoverflow;
962 }
963 *++yyssp = yystate = yytable[yyn];
964 *++yyvsp = yylval;
965 goto yyloop;
30
Control jumps to line 895
966 }
967 else
968 {
969#if YYDEBUG0
970 if (yydebug)
971 printf("%sdebug: error recovery discarding state %d\n",
972 YYPREFIX"yy", *yyssp);
973#endif
974 if (yyssp <= yyss) goto yyabort;
975 --yyssp;
976 --yyvsp;
977 }
978 }
979 }
980 else
981 {
982 if (yychar == 0) goto yyabort;
43
Assuming 'yychar' is not equal to 0
44
Taking false branch
983#if YYDEBUG0
984 if (yydebug)
985 {
986 yys = 0;
987 if (yychar <= YYMAXTOKEN271) yys = yyname[yychar];
988 if (!yys) yys = "illegal-symbol";
989 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
990 YYPREFIX"yy", yystate, yychar, yys);
991 }
992#endif
993 yychar = (-1);
994 goto yyloop;
45
Control jumps to line 895
995 }
996yyreduce:
997#if YYDEBUG0
998 if (yydebug)
999 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1000 YYPREFIX"yy", yystate, yyn, yyrule[yyn]);
1001#endif
1002 yym = yylen[yyn];
1003 if (yym
3.1
'yym' is 0
)
4
Taking false branch
34
Assuming 'yym' is not equal to 0
35
Taking true branch
49
Assuming 'yym' is 0
50
Taking false branch
1004 yyval = yyvsp[1-yym];
1005 else
1006 memset(&yyval, 0, sizeof yyval);
1007 switch (yyn)
5
'Default' branch taken. Execution continues on line 1227
36
Control jumps to 'case 24:' at line 1203
51
Control jumps to 'case 24:' at line 1203
1008 {
1009case 5:
1010#line 124 "/usr/src/sbin/dhcpleased/parse.y"
1011{ file->errors++; }
1012break;
1013case 6:
1014#line 127 "/usr/src/sbin/dhcpleased/parse.y"
1015{
1016 if (asprintf(&yyval.v.string, "%s %s", yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
1017 free(yyvsp[-1].v.string);
1018 free(yyvsp[0].v.string);
1019 yyerror("string: asprintf");
1020 YYERRORgoto yyerrlab;
1021 }
1022 free(yyvsp[-1].v.string);
1023 free(yyvsp[0].v.string);
1024 }
1025break;
1026case 8:
1027#line 140 "/usr/src/sbin/dhcpleased/parse.y"
1028{
1029 char *s = yyvsp[-2].v.string;
1030 if (log_getverbose() == 1)
1031 printf("%s = \"%s\"\n", yyvsp[-2].v.string, yyvsp[0].v.string);
1032 while (*s++) {
1033 if (isspace((unsigned char)*s)) {
1034 yyerror("macro name cannot contain "
1035 "whitespace");
1036 free(yyvsp[-2].v.string);
1037 free(yyvsp[0].v.string);
1038 YYERRORgoto yyerrlab;
1039 }
1040 }
1041 if (symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0) == -1)
1042 fatal("cannot store variable");
1043 free(yyvsp[-2].v.string);
1044 free(yyvsp[0].v.string);
1045 }
1046break;
1047case 12:
1048#line 167 "/usr/src/sbin/dhcpleased/parse.y"
1049{
1050 iface_conf = conf_get_iface(yyvsp[0].v.string);
1051 }
1052break;
1053case 13:
1054#line 169 "/usr/src/sbin/dhcpleased/parse.y"
1055{
1056 iface_conf = NULL((void *)0);
1057 }
1058break;
1059case 18:
1060#line 182 "/usr/src/sbin/dhcpleased/parse.y"
1061{
1062 ssize_t len;
1063 char buf[256];
1064
1065 if (iface_conf->vc_id != NULL((void *)0)) {
1066 yyerror("vendor class id already set");
1067 YYERRORgoto yyerrlab;
1068 }
1069
1070 len = strnunvis(buf, yyvsp[0].v.string, sizeof(buf));
1071 free(yyvsp[0].v.string);
1072
1073 if (len == -1) {
1074 yyerror("invalid vendor class id");
1075 YYERRORgoto yyerrlab;
1076 }
1077 if ((size_t)len >= sizeof(buf)) {
1078 yyerror("vendor class id too long");
1079 YYERRORgoto yyerrlab;
1080 }
1081
1082 iface_conf->vc_id_len = 2 + strlen(buf);
1083 iface_conf->vc_id = malloc(iface_conf->vc_id_len);
1084 if (iface_conf->vc_id == NULL((void *)0)) {
1085 yyerror("malloc");
1086 YYERRORgoto yyerrlab;
1087 }
1088 iface_conf->vc_id[0] = DHO_DHCP_CLASS_IDENTIFIER60;
1089 iface_conf->vc_id[1] = iface_conf->vc_id_len - 2;
1090 memcpy(&iface_conf->vc_id[2], buf,
1091 iface_conf->vc_id_len - 2);
1092 }
1093break;
1094case 19:
1095#line 214 "/usr/src/sbin/dhcpleased/parse.y"
1096{
1097 size_t i;
1098 ssize_t len;
1099 int not_hex = 0, val;
1100 char buf[256], *hex, *p, excess;
1101
1102 if (iface_conf->c_id != NULL((void *)0)) {
1103 yyerror("client-id already set");
1104 YYERRORgoto yyerrlab;
1105 }
1106
1107 /* parse as hex string including the type byte */
1108 if ((hex = strdup(yyvsp[0].v.string)) == NULL((void *)0)) {
1109 free(yyvsp[0].v.string);
1110 yyerror("malloc");
1111 YYERRORgoto yyerrlab;
1112 }
1113 for (i = 0; (p = strsep(&hex, ":")) != NULL((void *)0) && i <
1114 sizeof(buf); ) {
1115 if (sscanf(p, "%x%c", &val, &excess) != 1 ||
1116 val < 0 || val > 0xff) {
1117 not_hex = 1;
1118 break;
1119 }
1120 buf[i++] = (val & 0xff);
1121 }
1122 if (p != NULL((void *)0) && i == sizeof(buf))
1123 not_hex = 1;
1124 free(hex);
1125
1126 if (not_hex) {
1127 len = strnunvis(buf, yyvsp[0].v.string, sizeof(buf));
1128 free(yyvsp[0].v.string);
1129
1130 if (len == -1) {
1131 yyerror("invalid client-id");
1132 YYERRORgoto yyerrlab;
1133 }
1134 if ((size_t)len >= sizeof(buf)) {
1135 yyerror("client-id too long");
1136 YYERRORgoto yyerrlab;
1137 }
1138 iface_conf->c_id_len = 2 + len;
1139 iface_conf->c_id = malloc(iface_conf->c_id_len);
1140 if (iface_conf->c_id == NULL((void *)0)) {
1141 yyerror("malloc");
1142 YYERRORgoto yyerrlab;
1143 }
1144 memcpy(&iface_conf->c_id[2], buf,
1145 iface_conf->c_id_len - 2);
1146 } else {
1147 free(yyvsp[0].v.string);
1148 iface_conf->c_id_len = 2 + i;
1149 iface_conf->c_id = malloc(iface_conf->c_id_len);
1150 if (iface_conf->c_id == NULL((void *)0)) {
1151 yyerror("malloc");
1152 YYERRORgoto yyerrlab;
1153 }
1154 memcpy(&iface_conf->c_id[2], buf,
1155 iface_conf->c_id_len - 2);
1156 }
1157 iface_conf->c_id[0] = DHO_DHCP_CLIENT_IDENTIFIER61;
1158 iface_conf->c_id[1] = iface_conf->c_id_len - 2;
1159 }
1160break;
1161case 20:
1162#line 278 "/usr/src/sbin/dhcpleased/parse.y"
1163{
1164 if (iface_conf->h_name != NULL((void *)0)) {
1165 free(yyvsp[0].v.string);
1166 yyerror("host name already set");
1167 YYERRORgoto yyerrlab;
1168 }
1169 if (strlen(yyvsp[0].v.string) > 255) {
1170 free(yyvsp[0].v.string);
1171 yyerror("host name too long");
1172 YYERRORgoto yyerrlab;
1173 }
1174 iface_conf->h_name = yyvsp[0].v.string;
1175 }
1176break;
1177case 21:
1178#line 291 "/usr/src/sbin/dhcpleased/parse.y"
1179{
1180 if (iface_conf->h_name != NULL((void *)0)) {
1181 yyerror("host name already set");
1182 YYERRORgoto yyerrlab;
1183 }
1184
1185 if ((iface_conf->h_name = strdup("")) == NULL((void *)0)) {
1186 yyerror("malloc");
1187 YYERRORgoto yyerrlab;
1188 }
1189 }
1190break;
1191case 22:
1192#line 302 "/usr/src/sbin/dhcpleased/parse.y"
1193{
1194 iface_conf->ignore |= IGN_ROUTES1;
1195 }
1196break;
1197case 23:
1198#line 305 "/usr/src/sbin/dhcpleased/parse.y"
1199{
1200 iface_conf->ignore |= IGN_DNS2;
1201 }
1202break;
1203case 24:
1204#line 308 "/usr/src/sbin/dhcpleased/parse.y"
1205{
1206 int res;
1207
1208 if (iface_conf->ignore_servers_len >= MAX_SERVERS16) {
37
Assuming field 'ignore_servers_len' is >= MAX_SERVERS
38
Taking true branch
52
Assuming field 'ignore_servers_len' is < MAX_SERVERS
53
Taking false branch
1209 yyerror("too many servers to ignore");
1210 free(yyvsp[0].v.string);
39
Memory is released
1211 YYERRORgoto yyerrlab;
40
Control jumps to line 944
1212 }
1213 res = inet_pton(AF_INET2, yyvsp[0].v.string,
54
Use of memory after it is freed
1214 &iface_conf->ignore_servers[
1215 iface_conf->ignore_servers_len++]);
1216
1217 if (res != 1) {
1218 yyerror("Invalid server IP %s", yyvsp[0].v.string);
1219 free(yyvsp[0].v.string);
1220 YYERRORgoto yyerrlab;
1221 }
1222 free(yyvsp[0].v.string);
1223 }
1224break;
1225#line 1218 "parse.c"
1226 }
1227 yyssp -= yym;
1228 yystate = *yyssp;
1229 yyvsp -= yym;
1230 yym = yylhs[yyn];
1231 if (yystate
5.1
'yystate' is equal to 0
== 0 && yym
5.2
'yym' is equal to 0
== 0)
6
Taking true branch
1232 {
1233#if YYDEBUG0
1234 if (yydebug)
1235 printf("%sdebug: after reduction, shifting from state 0 to\
1236 state %d\n", YYPREFIX"yy", YYFINAL1);
1237#endif
1238 yystate = YYFINAL1;
1239 *++yyssp = YYFINAL1;
1240 *++yyvsp = yyval;
1241 if (yychar
6.1
'yychar' is < 0
< 0)
7
Taking true branch
1242 {
1243 if ((yychar = yylex()) < 0) yychar = 0;
8
Assuming the condition is false
9
Taking false branch
1244#if YYDEBUG0
1245 if (yydebug)
1246 {
1247 yys = 0;
1248 if (yychar <= YYMAXTOKEN271) yys = yyname[yychar];
1249 if (!yys) yys = "illegal-symbol";
1250 printf("%sdebug: state %d, reading %d (%s)\n",
1251 YYPREFIX"yy", YYFINAL1, yychar, yys);
1252 }
1253#endif
1254 }
1255 if (yychar == 0) goto yyaccept;
10
Assuming 'yychar' is not equal to 0
11
Taking false branch
1256 goto yyloop;
12
Control jumps to line 895
1257 }
1258 if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1259 yyn <= YYTABLESIZE260 && yycheck[yyn] == yystate)
1260 yystate = yytable[yyn];
1261 else
1262 yystate = yydgoto[yym];
1263#if YYDEBUG0
1264 if (yydebug)
1265 printf("%sdebug: after reduction, shifting from state %d \
1266to state %d\n", YYPREFIX"yy", *yyssp, yystate);
1267#endif
1268 if (yyssp >= yysslim && yygrowstack())
1269 {
1270 goto yyoverflow;
1271 }
1272 *++yyssp = yystate;
1273 *++yyvsp = yyval;
1274 goto yyloop;
1275yyoverflow:
1276 yyerror("yacc stack overflow");
1277yyabort:
1278 if (yyss)
1279 free(yyss);
1280 if (yyvs)
1281 free(yyvs);
1282 yyss = yyssp = NULL((void *)0);
1283 yyvs = yyvsp = NULL((void *)0);
1284 yystacksize = 0;
1285 return (1);
1286yyaccept:
1287 if (yyss)
1288 free(yyss);
1289 if (yyvs)
1290 free(yyvs);
1291 yyss = yyssp = NULL((void *)0);
1292 yyvs = yyvsp = NULL((void *)0);
1293 yystacksize = 0;
1294 return (0);
1295}