Infinite loop when loading masterfile with INCLUDE directive
When loading a zonefile, eg via ./named-compilezone -d -i full -o /dev/null x input
we can
enter another endless loop, when the file just contains $INCLUDE .
.
The loop happens via:
#0 load_text (lctx=0x7ffff1a54300) at master.c:1083
#1 0x00007ffff78042f6 in dns_master_loadfile (master_file=<optimized out>, top=<optimized out>, origin=<optimized out>, zclass=<optimized out>, options=<optimized out>, resign=<optimized out>, callbacks=<optimized out>,
include_cb=<optimized out>, include_arg=<optimized out>, mctx=<optimized out>, format=<optimized out>, maxttl=<optimized out>) at master.c:2637
#2 0x00007ffff7bbd66b in zone_startload (db=0x7ffff1a18800, zone=<optimized out>, zone@entry=0x7ffff1a90000, loadtime=...) at zone.c:2641
#3 0x00007ffff7b6e362 in zone_load (zone=<optimized out>, flags=<optimized out>, locked=<optimized out>) at zone.c:2315
#4 0x000055555563cd3d in load_zone (mctx=<optimized out>, zonename=<optimized out>, filename=<optimized out>, fileformat=<optimized out>, classname=<optimized out>, maxttl=<optimized out>, zonep=<optimized out>)
at check-tool.c:639
#5 0x000055555563afb0 in main (argc=<optimized out>, argv=<optimized out>) at named-checkzone.c:546
In load_text()
there is an infinite loop:
while (true) {
...
} else if (strcasecmp(DNS_AS_STR(token), "$INCLUDE") ==
0)
{
COMMITALL;
...
GETTOKEN(lctx->lex, ISC_LEXOPT_QSTRING, &token,
false);
if (include_file != NULL) {
isc_mem_free(mctx, include_file);
}
...
next_line:;
}
Since gettoken()
returns ISC_R_NOTFILE
the jump to next_line
is taken
and the parser ends up in an infinite loop. Catching ISC_R_NOTFILE
with ISC_R_UNEXPECTED
solves the issue.
#define GETTOKENERR(lexer, options, token, eol, err) \
do { \
result = gettoken(lexer, options, token, eol, callbacks); \
switch (result) { \
case ISC_R_SUCCESS: \
break; \
case ISC_R_UNEXPECTED: \
goto insist_and_cleanup; \
default: \
if (MANYERRS(lctx, result)) { \
SETRESULT(lctx, result); \
LOGIT(result); \
read_till_eol = true; \
err goto next_line; \
...
} while (0)
#define GETTOKEN(lexer, options, token, eol) \
GETTOKENERR(lexer, options, token, eol, {})