2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 06:55:30 +00:00

Remove infinite loop on ISC_R_NOFILE

When parsing a zonefile named-checkzone (and others) could loop
infinitely if a directory was $INCLUDED.  Record the error and treat
as EOF when looking for multiple errors.

This was found by Eric Sesterhenn from X41.
This commit is contained in:
Mark Andrews
2024-01-18 18:54:09 +11:00
parent 1a12fac371
commit efd27bb82d

View File

@@ -204,33 +204,52 @@ grow_rdata(int, dns_rdata_t *, int, rdatalist_head_t *, rdatalist_head_t *,
static void static void
loadctx_destroy(dns_loadctx_t *lctx); loadctx_destroy(dns_loadctx_t *lctx);
#define GETTOKENERR(lexer, options, token, eol, err) \ #define LCTX_MANYERRORS(lctx) (((lctx)->options & DNS_MASTER_MANYERRORS) != 0)
do { \
result = gettoken(lexer, options, token, eol, callbacks); \ #define GETTOKENERR(lexer, options, token, eol, err) \
switch (result) { \ do { \
case ISC_R_SUCCESS: \ result = gettoken(lexer, options, token, eol, callbacks); \
break; \ switch (result) { \
case ISC_R_UNEXPECTED: \ case ISC_R_SUCCESS: \
goto insist_and_cleanup; \ break; \
default: \ case ISC_R_NOTFILE: \
if (MANYERRS(lctx, result)) { \ /* Treat "bad" $INCLUDE as eof. */ \
SETRESULT(lctx, result); \ if (ictx->parent != NULL && LCTX_MANYERRORS(lctx)) { \
LOGIT(result); \ SETRESULT(lctx, result); \
read_till_eol = true; \ COMMITALL; \
err goto next_line; \ lctx->inc = ictx->parent; \
} else \ ictx->parent = NULL; \
goto log_and_cleanup; \ incctx_destroy(lctx->mctx, ictx); \
} \ RUNTIME_CHECK(isc_lex_close(lctx->lex) == \
if ((token)->type == isc_tokentype_special) { \ ISC_R_SUCCESS); \
result = DNS_R_SYNTAX; \ line = isc_lex_getsourceline(lctx->lex); \
if (MANYERRS(lctx, result)) { \ POST(line); \
SETRESULT(lctx, result); \ source = isc_lex_getsourcename(lctx->lex); \
LOGIT(result); \ ictx = lctx->inc; \
read_till_eol = true; \ continue; \
goto next_line; \ } \
} else \ goto insist_and_cleanup; \
goto log_and_cleanup; \ 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; \
} else \
goto log_and_cleanup; \
} \
if ((token)->type == isc_tokentype_special) { \
result = DNS_R_SYNTAX; \
if (MANYERRS(lctx, result)) { \
SETRESULT(lctx, result); \
LOGIT(result); \
read_till_eol = true; \
goto next_line; \
} else \
goto log_and_cleanup; \
} \
} while (0) } while (0)
#define GETTOKEN(lexer, options, token, eol) \ #define GETTOKEN(lexer, options, token, eol) \
GETTOKENERR(lexer, options, token, eol, {}) GETTOKENERR(lexer, options, token, eol, {})
@@ -283,7 +302,7 @@ loadctx_destroy(dns_loadctx_t *lctx);
#define MANYERRS(lctx, result) \ #define MANYERRS(lctx, result) \
((result != ISC_R_SUCCESS) && (result != ISC_R_IOERROR) && \ ((result != ISC_R_SUCCESS) && (result != ISC_R_IOERROR) && \
((lctx)->options & DNS_MASTER_MANYERRORS) != 0) LCTX_MANYERRORS(lctx))
#define SETRESULT(lctx, r) \ #define SETRESULT(lctx, r) \
if ((lctx)->result == ISC_R_SUCCESS) { \ if ((lctx)->result == ISC_R_SUCCESS) { \