mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-22 09:57:20 +00:00
Check whether files are zero length before parsing them [rt17757]
This commit is contained in:
parent
e6270e4f99
commit
c40e954c55
2
RELNOTES
2
RELNOTES
@ -50,6 +50,8 @@ work on other platforms. Please report any problems and suggested fixes to
|
|||||||
|
|
||||||
Changes since 4.1.0a1
|
Changes since 4.1.0a1
|
||||||
|
|
||||||
|
- Check whether files are zero length before trying to parse them.
|
||||||
|
|
||||||
- Ari Edelkind's PARANOIA patch has been included and may be compiled in
|
- Ari Edelkind's PARANOIA patch has been included and may be compiled in
|
||||||
via two ./configure parameters, --enable-paranoia and
|
via two ./configure parameters, --enable-paranoia and
|
||||||
--enable-early-chroot.
|
--enable-early-chroot.
|
||||||
|
@ -59,6 +59,7 @@ isc_result_t read_client_conf ()
|
|||||||
{
|
{
|
||||||
struct client_config *config;
|
struct client_config *config;
|
||||||
struct interface_info *ip;
|
struct interface_info *ip;
|
||||||
|
struct parse *parse;
|
||||||
isc_result_t status;
|
isc_result_t status;
|
||||||
unsigned code;
|
unsigned code;
|
||||||
|
|
||||||
@ -147,26 +148,27 @@ isc_result_t read_client_conf ()
|
|||||||
status = read_client_conf_file (path_dhclient_conf,
|
status = read_client_conf_file (path_dhclient_conf,
|
||||||
(struct interface_info *)0,
|
(struct interface_info *)0,
|
||||||
&top_level_config);
|
&top_level_config);
|
||||||
|
|
||||||
|
parse = NULL;
|
||||||
if (status != ISC_R_SUCCESS) {
|
if (status != ISC_R_SUCCESS) {
|
||||||
;
|
;
|
||||||
#ifdef LATER
|
#ifdef LATER
|
||||||
/* Set up the standard name service updater routine. */
|
/* Set up the standard name service updater routine. */
|
||||||
parse = (struct parse *)0;
|
status = new_parse(&parse, -1, default_client_config,
|
||||||
status = new_parse (&parse, -1, default_client_config,
|
sizeof(default_client_config) - 1,
|
||||||
(sizeof default_client_config) - 1,
|
"default client configuration", 0);
|
||||||
"default client configuration", 0);
|
|
||||||
if (status != ISC_R_SUCCESS)
|
if (status != ISC_R_SUCCESS)
|
||||||
log_fatal ("can't begin default client config!");
|
log_fatal ("can't begin default client config!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parse != NULL) {
|
||||||
do {
|
do {
|
||||||
token = peek_token (&val, (unsigned *)0, cfile);
|
token = peek_token(&val, NULL, cfile);
|
||||||
if (token == END_OF_FILE)
|
if (token == END_OF_FILE)
|
||||||
break;
|
break;
|
||||||
parse_client_statement (cfile,
|
parse_client_statement(cfile, NULL, &top_level_config);
|
||||||
(struct interface_info *)0,
|
|
||||||
&top_level_config);
|
|
||||||
} while (1);
|
} while (1);
|
||||||
end_parse (&parse);
|
end_parse(&parse);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,8 +213,10 @@ int read_client_conf_file (const char *name, struct interface_info *ip,
|
|||||||
if ((file = open (name, O_RDONLY)) < 0)
|
if ((file = open (name, O_RDONLY)) < 0)
|
||||||
return uerr2isc (errno);
|
return uerr2isc (errno);
|
||||||
|
|
||||||
cfile = (struct parse *)0;
|
cfile = NULL;
|
||||||
new_parse (&cfile, file, (char *)0, 0, path_dhclient_conf, 0);
|
status = new_parse(&cfile, file, NULL, 0, path_dhclient_conf, 0);
|
||||||
|
if (status != ISC_R_SUCCESS || cfile == NULL)
|
||||||
|
return status;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
token = peek_token (&val, (unsigned *)0, cfile);
|
token = peek_token (&val, (unsigned *)0, cfile);
|
||||||
@ -236,6 +240,7 @@ int read_client_conf_file (const char *name, struct interface_info *ip,
|
|||||||
void read_client_leases ()
|
void read_client_leases ()
|
||||||
{
|
{
|
||||||
int file;
|
int file;
|
||||||
|
isc_result_t status;
|
||||||
struct parse *cfile;
|
struct parse *cfile;
|
||||||
const char *val;
|
const char *val;
|
||||||
int token;
|
int token;
|
||||||
@ -244,10 +249,10 @@ void read_client_leases ()
|
|||||||
we can safely trust the server to remember our state. */
|
we can safely trust the server to remember our state. */
|
||||||
if ((file = open (path_dhclient_db, O_RDONLY)) < 0)
|
if ((file = open (path_dhclient_db, O_RDONLY)) < 0)
|
||||||
return;
|
return;
|
||||||
cfile = (struct parse *)0;
|
|
||||||
/* new_parse() may fail if the file is of zero length. */
|
cfile = NULL;
|
||||||
if (new_parse(&cfile, file, (char *)0, 0,
|
status = new_parse(&cfile, file, NULL, 0, path_dhclient_db, 0);
|
||||||
path_dhclient_db, 0) != ISC_R_SUCCESS)
|
if (status != ISC_R_SUCCESS || cfile == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -174,12 +174,12 @@ isc_result_t dhcp_group_set_value (omapi_object_t *h,
|
|||||||
value -> type == omapi_datatype_string) {
|
value -> type == omapi_datatype_string) {
|
||||||
struct parse *parse;
|
struct parse *parse;
|
||||||
int lose = 0;
|
int lose = 0;
|
||||||
parse = (struct parse *)0;
|
parse = NULL;
|
||||||
status = new_parse (&parse, -1,
|
status = new_parse(&parse, -1,
|
||||||
(char *)value -> u.buffer.value,
|
(char *) value->u.buffer.value,
|
||||||
value -> u.buffer.len,
|
value->u.buffer.len,
|
||||||
"network client", 0);
|
"network client", 0);
|
||||||
if (status != ISC_R_SUCCESS)
|
if (status != ISC_R_SUCCESS || parse == NULL)
|
||||||
return status;
|
return status;
|
||||||
if (!(parse_executable_statements
|
if (!(parse_executable_statements
|
||||||
(&group -> group -> statements, parse, &lose,
|
(&group -> group -> statements, parse, &lose,
|
||||||
|
@ -52,21 +52,18 @@ isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
|
|||||||
const char *name;
|
const char *name;
|
||||||
int eolp;
|
int eolp;
|
||||||
{
|
{
|
||||||
|
isc_result_t status = ISC_R_SUCCESS;
|
||||||
struct parse *tmp;
|
struct parse *tmp;
|
||||||
|
|
||||||
tmp = dmalloc(sizeof(struct parse), MDL);
|
tmp = dmalloc(sizeof(struct parse), MDL);
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
return ISC_R_NOMEMORY;
|
return (ISC_R_NOMEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't need to initialize things to zero here, since
|
* We don't need to initialize things to zero here, since
|
||||||
* dmalloc() returns memory that is set to zero.
|
* dmalloc() returns memory that is set to zero.
|
||||||
*/
|
*/
|
||||||
/* tmp->token = 0; */
|
|
||||||
/* tmp->warnings_occurred = 0; */
|
|
||||||
/* tmp->bufix = 0; */
|
|
||||||
/* tmp->saved_state = NULL; */
|
|
||||||
tmp->tlname = name;
|
tmp->tlname = name;
|
||||||
tmp->lpos = tmp -> line = 1;
|
tmp->lpos = tmp -> line = 1;
|
||||||
tmp->cur_line = tmp->line1;
|
tmp->cur_line = tmp->line1;
|
||||||
@ -83,20 +80,30 @@ isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
|
|||||||
} else {
|
} else {
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
|
||||||
if (fstat(file, &sb) < 0)
|
if (fstat(file, &sb) < 0) {
|
||||||
return ISC_R_IOERROR;
|
status = ISC_R_IOERROR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
tmp->bufsiz = tmp->buflen = (size_t)sb.st_size;
|
if (sb.st_size == 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
tmp->bufsiz = tmp->buflen = (size_t) sb.st_size;
|
||||||
tmp->inbuf = mmap(NULL, tmp->bufsiz, PROT_READ, MAP_SHARED,
|
tmp->inbuf = mmap(NULL, tmp->bufsiz, PROT_READ, MAP_SHARED,
|
||||||
file, 0);
|
file, 0);
|
||||||
|
|
||||||
if (tmp->inbuf == MAP_FAILED) {
|
if (tmp->inbuf == MAP_FAILED) {
|
||||||
return ISC_R_IOERROR;
|
status = ISC_R_IOERROR;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*cfile = tmp;
|
*cfile = tmp;
|
||||||
return ISC_R_SUCCESS;
|
return (ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
dfree(tmp, MDL);
|
||||||
|
return (status);
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t end_parse (cfile)
|
isc_result_t end_parse (cfile)
|
||||||
|
@ -47,14 +47,17 @@ void read_resolv_conf (parse_time)
|
|||||||
int token;
|
int token;
|
||||||
struct name_server *sp, *sl, *ns;
|
struct name_server *sp, *sl, *ns;
|
||||||
struct domain_search_list *dp, *dl, *nd;
|
struct domain_search_list *dp, *dl, *nd;
|
||||||
|
isc_result_t status;
|
||||||
|
|
||||||
if ((file = open (path_resolv_conf, O_RDONLY)) < 0) {
|
if ((file = open (path_resolv_conf, O_RDONLY)) < 0) {
|
||||||
log_error ("Can't open %s: %m", path_resolv_conf);
|
log_error ("Can't open %s: %m", path_resolv_conf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cfile = (struct parse *)0;
|
cfile = NULL;
|
||||||
new_parse (&cfile, file, (char *)0, 0, path_resolv_conf, 1);
|
status = new_parse(&cfile, file, NULL, 0, path_resolv_conf, 1);
|
||||||
|
if (status != ISC_R_SUCCESS || cfile == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
token = next_token (&val, (unsigned *)0, cfile);
|
token = next_token (&val, (unsigned *)0, cfile);
|
||||||
|
@ -157,10 +157,13 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
|
|||||||
/* If we're recording, write out the filename and file contents. */
|
/* If we're recording, write out the filename and file contents. */
|
||||||
if (trace_record ())
|
if (trace_record ())
|
||||||
trace_write_packet (ttype, ulen + tflen + 1, dbuf, MDL);
|
trace_write_packet (ttype, ulen + tflen + 1, dbuf, MDL);
|
||||||
new_parse (&cfile, -1, fbuf, ulen, filename, 0); /* XXX */
|
status = new_parse(&cfile, -1, fbuf, ulen, filename, 0); /* XXX */
|
||||||
#else
|
#else
|
||||||
new_parse (&cfile, file, (char *)0, 0, filename, 0);
|
status = new_parse(&cfile, file, NULL, 0, filename, 0);
|
||||||
#endif
|
#endif
|
||||||
|
if (status != ISC_R_SUCCESS || cfile == NULL)
|
||||||
|
return status;
|
||||||
|
|
||||||
if (leasep)
|
if (leasep)
|
||||||
status = lease_file_subparse (cfile);
|
status = lease_file_subparse (cfile);
|
||||||
else
|
else
|
||||||
@ -181,6 +184,7 @@ void trace_conf_input (trace_type_t *ttype, unsigned len, char *data)
|
|||||||
struct parse *cfile = (struct parse *)0;
|
struct parse *cfile = (struct parse *)0;
|
||||||
static int postconf_initialized;
|
static int postconf_initialized;
|
||||||
static int leaseconf_initialized;
|
static int leaseconf_initialized;
|
||||||
|
isc_result_t status;
|
||||||
|
|
||||||
/* Do what's done above, except that we don't have to read in the
|
/* Do what's done above, except that we don't have to read in the
|
||||||
data, because it's already been read for us. */
|
data, because it's already been read for us. */
|
||||||
@ -191,12 +195,15 @@ void trace_conf_input (trace_type_t *ttype, unsigned len, char *data)
|
|||||||
/* If we're recording, write out the filename and file contents. */
|
/* If we're recording, write out the filename and file contents. */
|
||||||
if (trace_record ())
|
if (trace_record ())
|
||||||
trace_write_packet (ttype, len, data, MDL);
|
trace_write_packet (ttype, len, data, MDL);
|
||||||
new_parse (&cfile, -1, fbuf, flen, data, 0);
|
|
||||||
if (ttype == trace_readleases_type)
|
status = new_parse(&cfile, -1, fbuf, flen, data, 0);
|
||||||
lease_file_subparse (cfile);
|
if (status == ISC_R_SUCCESS || cfile != NULL) {
|
||||||
else
|
if (ttype == trace_readleases_type)
|
||||||
conf_file_subparse (cfile, root_group, ROOT_GROUP);
|
lease_file_subparse (cfile);
|
||||||
end_parse (&cfile);
|
else
|
||||||
|
conf_file_subparse (cfile, root_group, ROOT_GROUP);
|
||||||
|
end_parse (&cfile);
|
||||||
|
}
|
||||||
|
|
||||||
/* Postconfiguration needs to be done after the config file
|
/* Postconfiguration needs to be done after the config file
|
||||||
has been loaded. */
|
has been loaded. */
|
||||||
|
@ -612,20 +612,21 @@ main(int argc, char **argv) {
|
|||||||
|
|
||||||
#if defined (NSUPDATE)
|
#if defined (NSUPDATE)
|
||||||
/* Set up the standard name service updater routine. */
|
/* Set up the standard name service updater routine. */
|
||||||
parse = (struct parse *)0;
|
parse = NULL;
|
||||||
status = new_parse (&parse, -1,
|
status = new_parse(&parse, -1, std_nsupdate, sizeof(std_nsupdate) - 1,
|
||||||
std_nsupdate, (sizeof std_nsupdate) - 1,
|
|
||||||
"standard name service update routine", 0);
|
"standard name service update routine", 0);
|
||||||
if (status != ISC_R_SUCCESS)
|
if (status != ISC_R_SUCCESS)
|
||||||
log_fatal ("can't begin parsing name service updater!");
|
log_fatal ("can't begin parsing name service updater!");
|
||||||
|
|
||||||
lose = 0;
|
if (parse != NULL) {
|
||||||
if (!(parse_executable_statements
|
lose = 0;
|
||||||
(&root_group -> statements, parse, &lose, context_any))) {
|
if (!(parse_executable_statements(&root_group->statements,
|
||||||
end_parse (&parse);
|
parse, &lose, context_any))) {
|
||||||
log_fatal ("can't parse standard name service updater!");
|
end_parse(&parse);
|
||||||
|
log_fatal("can't parse standard name service updater!");
|
||||||
|
}
|
||||||
|
end_parse(&parse);
|
||||||
}
|
}
|
||||||
end_parse (&parse);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initialize icmp support... */
|
/* Initialize icmp support... */
|
||||||
@ -1129,20 +1130,22 @@ void postconf_initialization (int quiet)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set up the standard name service updater routine. */
|
/* Set up the standard name service updater routine. */
|
||||||
parse = (struct parse *)0;
|
parse = NULL;
|
||||||
result = new_parse (&parse, -1,
|
result = new_parse(&parse, -1, old_nsupdate,
|
||||||
old_nsupdate, (sizeof old_nsupdate) - 1,
|
sizeof(old_nsupdate) - 1,
|
||||||
"old name service update routine", 0);
|
"old name service update routine", 0);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
log_fatal ("can't begin parsing old ddns updater!");
|
log_fatal ("can't begin parsing old ddns updater!");
|
||||||
|
|
||||||
tmp = 0;
|
if (parse != NULL) {
|
||||||
if (!(parse_executable_statements (e, parse,
|
tmp = 0;
|
||||||
&tmp, context_any))) {
|
if (!(parse_executable_statements(e, parse, &tmp,
|
||||||
end_parse (&parse);
|
context_any))) {
|
||||||
log_fatal ("can't parse standard ddns updater!");
|
end_parse(&parse);
|
||||||
|
log_fatal("can't parse standard ddns updater!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
end_parse (&parse);
|
end_parse(&parse);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1067,12 +1067,13 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h,
|
|||||||
struct parse *parse;
|
struct parse *parse;
|
||||||
int lose = 0;
|
int lose = 0;
|
||||||
parse = (struct parse *)0;
|
parse = (struct parse *)0;
|
||||||
status = new_parse (&parse, -1,
|
status = new_parse(&parse, -1,
|
||||||
(char *)value -> u.buffer.value,
|
(char *) value->u.buffer.value,
|
||||||
value -> u.buffer.len,
|
value->u.buffer.len,
|
||||||
"network client", 0);
|
"network client", 0);
|
||||||
if (status != ISC_R_SUCCESS)
|
if (status != ISC_R_SUCCESS || parse == NULL)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if (!(parse_executable_statements
|
if (!(parse_executable_statements
|
||||||
(&host -> group -> statements, parse, &lose,
|
(&host -> group -> statements, parse, &lose,
|
||||||
context_any))) {
|
context_any))) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user