2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-22 18:07:25 +00:00

Check whether files are zero length before parsing them [rt17757]

This commit is contained in:
Evan Hunt 2008-03-07 20:12:44 +00:00
parent e6270e4f99
commit c40e954c55
8 changed files with 91 additions and 63 deletions

View File

@ -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.

View File

@ -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,24 +148,25 @@ 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 {

View File

@ -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,

View File

@ -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;
}
if (sb.st_size == 0)
goto cleanup;
tmp->bufsiz = tmp->buflen = (size_t) sb.st_size; 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)

View File

@ -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);

View File

@ -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);
status = new_parse(&cfile, -1, fbuf, flen, data, 0);
if (status == ISC_R_SUCCESS || cfile != NULL) {
if (ttype == trace_readleases_type) if (ttype == trace_readleases_type)
lease_file_subparse (cfile); lease_file_subparse (cfile);
else else
conf_file_subparse (cfile, root_group, ROOT_GROUP); conf_file_subparse (cfile, root_group, ROOT_GROUP);
end_parse (&cfile); 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. */

View File

@ -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!");
if (parse != NULL) {
lose = 0; lose = 0;
if (!(parse_executable_statements if (!(parse_executable_statements(&root_group->statements,
(&root_group -> statements, parse, &lose, context_any))) { parse, &lose, context_any))) {
end_parse(&parse); end_parse(&parse);
log_fatal("can't parse standard name service updater!"); log_fatal("can't parse standard name service updater!");
} }
end_parse(&parse); end_parse(&parse);
}
#endif #endif
/* Initialize icmp support... */ /* Initialize icmp support... */
@ -1129,19 +1130,21 @@ 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!");
if (parse != NULL) {
tmp = 0; tmp = 0;
if (!(parse_executable_statements (e, parse, if (!(parse_executable_statements(e, parse, &tmp,
&tmp, context_any))) { context_any))) {
end_parse(&parse); end_parse(&parse);
log_fatal("can't parse standard ddns updater!"); log_fatal("can't parse standard ddns updater!");
} }
}
end_parse(&parse); end_parse(&parse);
} }
#endif #endif

View File

@ -1071,8 +1071,9 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h,
(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))) {