mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 14:07:59 +00:00
1134. [bug] Multithreaded servers could deadlock in ferror()
when reloading zone files. [RT #1951, #1998]
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -1,3 +1,6 @@
|
|||||||
|
1134. [bug] Multithreaded servers could deadlock in ferror()
|
||||||
|
when reloading zone files. [RT #1951, #1998]
|
||||||
|
|
||||||
1133. [bug] IN6_IS_ADDR_LOOPBACK was not portably defined on
|
1133. [bug] IN6_IS_ADDR_LOOPBACK was not portably defined on
|
||||||
platforms without IN6_IS_ADDR_LOOPBACK. [RT #2106]
|
platforms without IN6_IS_ADDR_LOOPBACK. [RT #2106]
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: lex.c,v 1.67 2001/11/16 10:50:00 marka Exp $ */
|
/* $Id: lex.c,v 1.68 2001/11/21 22:26:46 gson Exp $ */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -235,10 +235,6 @@ isc_lex_openfile(isc_lex_t *lex, const char *filename) {
|
|||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
|
|
||||||
#ifdef HAVE_FLOCKFILE
|
|
||||||
flockfile(stream);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
result = new_source(lex, ISC_TRUE, ISC_TRUE, stream, filename);
|
result = new_source(lex, ISC_TRUE, ISC_TRUE, stream, filename);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
fclose(stream);
|
fclose(stream);
|
||||||
@@ -255,9 +251,6 @@ isc_lex_openstream(isc_lex_t *lex, FILE *stream) {
|
|||||||
|
|
||||||
REQUIRE(VALID_LEX(lex));
|
REQUIRE(VALID_LEX(lex));
|
||||||
|
|
||||||
#ifdef HAVE_FLOCKFILE
|
|
||||||
flockfile(stream);
|
|
||||||
#endif
|
|
||||||
/* This is safe. */
|
/* This is safe. */
|
||||||
sprintf(name, "stream-%p", stream);
|
sprintf(name, "stream-%p", stream);
|
||||||
|
|
||||||
@@ -296,9 +289,6 @@ isc_lex_close(isc_lex_t *lex) {
|
|||||||
|
|
||||||
ISC_LIST_UNLINK(lex->sources, source, link);
|
ISC_LIST_UNLINK(lex->sources, source, link);
|
||||||
if (source->is_file) {
|
if (source->is_file) {
|
||||||
#ifdef HAVE_FLOCKFILE
|
|
||||||
funlockfile((FILE *)(source->input));
|
|
||||||
#endif
|
|
||||||
if (source->need_close)
|
if (source->need_close)
|
||||||
fclose((FILE *)(source->input));
|
fclose((FILE *)(source->input));
|
||||||
}
|
}
|
||||||
@@ -422,6 +412,12 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
|
|||||||
|
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
remaining = lex->max_token;
|
remaining = lex->max_token;
|
||||||
|
|
||||||
|
#ifdef HAVE_FLOCKFILE
|
||||||
|
if (source->is_file)
|
||||||
|
flockfile(source->input);
|
||||||
|
#endif
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (isc_buffer_remaininglength(source->pushback) == 0) {
|
if (isc_buffer_remaininglength(source->pushback) == 0) {
|
||||||
if (source->is_file) {
|
if (source->is_file) {
|
||||||
@@ -435,7 +431,8 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
|
|||||||
if (c == EOF) {
|
if (c == EOF) {
|
||||||
if (ferror(stream)) {
|
if (ferror(stream)) {
|
||||||
source->result = ISC_R_IOERROR;
|
source->result = ISC_R_IOERROR;
|
||||||
return (source->result);
|
result = source->result;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
source->at_eof = ISC_TRUE;
|
source->at_eof = ISC_TRUE;
|
||||||
}
|
}
|
||||||
@@ -453,8 +450,10 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
|
|||||||
}
|
}
|
||||||
if (c != EOF) {
|
if (c != EOF) {
|
||||||
source->result = pushandgrow(lex, source, c);
|
source->result = pushandgrow(lex, source, c);
|
||||||
if (source->result != ISC_R_SUCCESS)
|
if (source->result != ISC_R_SUCCESS) {
|
||||||
return (source->result);
|
result = source->result;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,10 +503,14 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
|
|||||||
if (c == EOF) {
|
if (c == EOF) {
|
||||||
lex->last_was_eol = ISC_FALSE;
|
lex->last_was_eol = ISC_FALSE;
|
||||||
if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 &&
|
if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 &&
|
||||||
lex->paren_count != 0)
|
lex->paren_count != 0) {
|
||||||
return (ISC_R_UNBALANCED);
|
result = ISC_R_UNBALANCED;
|
||||||
if ((options & ISC_LEXOPT_EOF) == 0)
|
goto done;
|
||||||
return (ISC_R_EOF);
|
}
|
||||||
|
if ((options & ISC_LEXOPT_EOF) == 0) {
|
||||||
|
result = ISC_R_EOF;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
tokenp->type = isc_tokentype_eof;
|
tokenp->type = isc_tokentype_eof;
|
||||||
done = ISC_TRUE;
|
done = ISC_TRUE;
|
||||||
} else if (c == ' ' || c == '\t') {
|
} else if (c == ' ' || c == '\t') {
|
||||||
@@ -542,8 +545,10 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
|
|||||||
options &= ~IWSEOL;
|
options &= ~IWSEOL;
|
||||||
lex->paren_count++;
|
lex->paren_count++;
|
||||||
} else {
|
} else {
|
||||||
if (lex->paren_count == 0)
|
if (lex->paren_count == 0) {
|
||||||
return (ISC_R_UNBALANCED);
|
result = ISC_R_UNBALANCED;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
lex->paren_count--;
|
lex->paren_count--;
|
||||||
if (lex->paren_count == 0)
|
if (lex->paren_count == 0)
|
||||||
options =
|
options =
|
||||||
@@ -586,7 +591,8 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
|
|||||||
as_ulong = strtoul(lex->data, &e, base);
|
as_ulong = strtoul(lex->data, &e, base);
|
||||||
if (as_ulong == ULONG_MAX &&
|
if (as_ulong == ULONG_MAX &&
|
||||||
errno == ERANGE) {
|
errno == ERANGE) {
|
||||||
return (ISC_R_RANGE);
|
result = ISC_R_RANGE;
|
||||||
|
goto done;
|
||||||
} else if (*e == 0) {
|
} else if (*e == 0) {
|
||||||
tokenp->type =
|
tokenp->type =
|
||||||
isc_tokentype_number;
|
isc_tokentype_number;
|
||||||
@@ -618,7 +624,7 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
|
|||||||
result = grow_data(lex, &remaining,
|
result = grow_data(lex, &remaining,
|
||||||
&curr, &prev);
|
&curr, &prev);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
return (result);
|
goto done;
|
||||||
}
|
}
|
||||||
INSIST(remaining > 0);
|
INSIST(remaining > 0);
|
||||||
*curr++ = c;
|
*curr++ = c;
|
||||||
@@ -630,8 +636,10 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
|
|||||||
(c == ' ' || c == '\t' || lex->specials[c])) ||
|
(c == ' ' || c == '\t' || lex->specials[c])) ||
|
||||||
c == '\r' || c == '\n' || c == EOF) {
|
c == '\r' || c == '\n' || c == EOF) {
|
||||||
pushback(source, c);
|
pushback(source, c);
|
||||||
if (source->result != ISC_R_SUCCESS)
|
if (source->result != ISC_R_SUCCESS) {
|
||||||
return (source->result);
|
result = source->result;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
tokenp->type = isc_tokentype_string;
|
tokenp->type = isc_tokentype_string;
|
||||||
tokenp->value.as_textregion.base = lex->data;
|
tokenp->value.as_textregion.base = lex->data;
|
||||||
tokenp->value.as_textregion.length =
|
tokenp->value.as_textregion.length =
|
||||||
@@ -646,7 +654,7 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
|
|||||||
result = grow_data(lex, &remaining,
|
result = grow_data(lex, &remaining,
|
||||||
&curr, &prev);
|
&curr, &prev);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
return (result);
|
goto done;
|
||||||
}
|
}
|
||||||
INSIST(remaining > 0);
|
INSIST(remaining > 0);
|
||||||
*curr++ = c;
|
*curr++ = c;
|
||||||
@@ -669,14 +677,18 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
|
|||||||
state = saved_state;
|
state = saved_state;
|
||||||
goto no_read;
|
goto no_read;
|
||||||
case lexstate_ccomment:
|
case lexstate_ccomment:
|
||||||
if (c == EOF)
|
if (c == EOF) {
|
||||||
return (ISC_R_UNEXPECTEDEND);
|
result = ISC_R_UNEXPECTEDEND;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (c == '*')
|
if (c == '*')
|
||||||
state = lexstate_ccommentend;
|
state = lexstate_ccommentend;
|
||||||
break;
|
break;
|
||||||
case lexstate_ccommentend:
|
case lexstate_ccommentend:
|
||||||
if (c == EOF)
|
if (c == EOF) {
|
||||||
return (ISC_R_UNEXPECTEDEND);
|
result = ISC_R_UNEXPECTEDEND;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (c == '/') {
|
if (c == '/') {
|
||||||
/*
|
/*
|
||||||
* C-style comments become a single space.
|
* C-style comments become a single space.
|
||||||
@@ -692,8 +704,10 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
|
|||||||
state = lexstate_ccomment;
|
state = lexstate_ccomment;
|
||||||
break;
|
break;
|
||||||
case lexstate_eatline:
|
case lexstate_eatline:
|
||||||
if (c == EOF)
|
if (c == EOF) {
|
||||||
return (ISC_R_UNEXPECTEDEND);
|
result = ISC_R_UNEXPECTEDEND;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
no_comments = ISC_FALSE;
|
no_comments = ISC_FALSE;
|
||||||
state = saved_state;
|
state = saved_state;
|
||||||
@@ -701,8 +715,10 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case lexstate_qstring:
|
case lexstate_qstring:
|
||||||
if (c == EOF)
|
if (c == EOF) {
|
||||||
return (ISC_R_UNEXPECTEDEND);
|
result = ISC_R_UNEXPECTEDEND;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (c == '"') {
|
if (c == '"') {
|
||||||
if (escaped) {
|
if (escaped) {
|
||||||
escaped = ISC_FALSE;
|
escaped = ISC_FALSE;
|
||||||
@@ -724,7 +740,8 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
|
|||||||
if (c == '\n' && !escaped &&
|
if (c == '\n' && !escaped &&
|
||||||
(options & ISC_LEXOPT_QSTRINGMULTILINE) == 0) {
|
(options & ISC_LEXOPT_QSTRINGMULTILINE) == 0) {
|
||||||
pushback(source, c);
|
pushback(source, c);
|
||||||
return (ISC_R_UNBALANCEDQUOTES);
|
result = ISC_R_UNBALANCEDQUOTES;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
if (c == '\\' && !escaped)
|
if (c == '\\' && !escaped)
|
||||||
escaped = ISC_TRUE;
|
escaped = ISC_TRUE;
|
||||||
@@ -734,7 +751,7 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
|
|||||||
result = grow_data(lex, &remaining,
|
result = grow_data(lex, &remaining,
|
||||||
&curr, &prev);
|
&curr, &prev);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
return (result);
|
goto done;
|
||||||
}
|
}
|
||||||
INSIST(remaining > 0);
|
INSIST(remaining > 0);
|
||||||
prev = curr;
|
prev = curr;
|
||||||
@@ -754,7 +771,13 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
|
|||||||
|
|
||||||
} while (!done);
|
} while (!done);
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
result = ISC_R_SUCCESS;
|
||||||
|
done:
|
||||||
|
#ifdef HAVE_FLOCKFILE
|
||||||
|
if (source->is_file)
|
||||||
|
funlockfile(source->input);
|
||||||
|
#endif
|
||||||
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
|
Reference in New Issue
Block a user