]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Check whether files are zero length before parsing them [rt17757]
authorEvan Hunt <each@isc.org>
Fri, 7 Mar 2008 20:12:44 +0000 (20:12 +0000)
committerEvan Hunt <each@isc.org>
Fri, 7 Mar 2008 20:12:44 +0000 (20:12 +0000)
RELNOTES
client/clparse.c
common/comapi.c
common/conflex.c
common/resolv.c
server/confpars.c
server/dhcpd.c
server/omapi.c

index 7e054ad5544ec034f42fba6583c12f41e4f50cfd..15d55f612e5bba30acff7dc0005b78b883a7e235 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -50,6 +50,8 @@ work on other platforms. Please report any problems and suggested fixes to
 
                        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
   via two ./configure parameters, --enable-paranoia and
   --enable-early-chroot.
index 34fa93da2502ba57e8df7bd1384d6020f58b1c89..e5f4e81ce3bc42a83d45d7f46d972f0e4baf3687 100644 (file)
@@ -59,6 +59,7 @@ isc_result_t read_client_conf ()
 {
        struct client_config *config;
        struct interface_info *ip;
+       struct parse *parse;
        isc_result_t status;
        unsigned code;
 
@@ -147,26 +148,27 @@ isc_result_t read_client_conf ()
        status = read_client_conf_file (path_dhclient_conf,
                                        (struct interface_info *)0,
                                        &top_level_config);
+
+       parse = NULL;
        if (status != ISC_R_SUCCESS) {
                ;
 #ifdef LATER
                /* Set up the standard name service updater routine. */
-               parse = (struct parse *)0;
-               status = new_parse (&parse, -1, default_client_config,
-                                   (sizeof default_client_config) - 1,
-                                   "default client configuration", 0);
+               status = new_parse(&parse, -1, default_client_config,
+                                  sizeof(default_client_config) - 1,
+                                  "default client configuration", 0);
                if (status != ISC_R_SUCCESS)
                        log_fatal ("can't begin default client config!");
+       }
 
+       if (parse != NULL) {
                do {
-                       token = peek_token (&val, (unsigned *)0, cfile);
+                       token = peek_token(&val, NULL, cfile);
                        if (token == END_OF_FILE)
                                break;
-                       parse_client_statement (cfile,
-                                               (struct interface_info *)0,
-                                               &top_level_config);
+                       parse_client_statement(cfile, NULL, &top_level_config);
                } while (1);
-               end_parse (&parse);
+               end_parse(&parse);
 #endif
        }
 
@@ -211,8 +213,10 @@ int read_client_conf_file (const char *name, struct interface_info *ip,
        if ((file = open (name, O_RDONLY)) < 0)
                return uerr2isc (errno);
 
-       cfile = (struct parse *)0;
-       new_parse (&cfile, file, (char *)0, 0, path_dhclient_conf, 0);
+       cfile = NULL;
+       status = new_parse(&cfile, file, NULL, 0, path_dhclient_conf, 0);
+       if (status != ISC_R_SUCCESS || cfile == NULL)
+               return status;
 
        do {
                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 ()
 {
        int file;
+       isc_result_t status;
        struct parse *cfile;
        const char *val;
        int token;
@@ -244,10 +249,10 @@ void read_client_leases ()
           we can safely trust the server to remember our state. */
        if ((file = open (path_dhclient_db, O_RDONLY)) < 0)
                return;
-       cfile = (struct parse *)0;
-       /* new_parse() may fail if the file is of zero length. */
-       if (new_parse(&cfile, file, (char *)0, 0,
-                     path_dhclient_db, 0) != ISC_R_SUCCESS)
+
+       cfile = NULL;
+       status = new_parse(&cfile, file, NULL, 0, path_dhclient_db, 0);
+       if (status != ISC_R_SUCCESS || cfile == NULL)
                return;
 
        do {
index a173360b1d5573cd58cb8c8a7f9167d360545166..37e7b1e7ccf235b1a0f78880fe7c412ff784d93f 100644 (file)
@@ -174,12 +174,12 @@ isc_result_t dhcp_group_set_value  (omapi_object_t *h,
                    value -> type == omapi_datatype_string) {
                        struct parse *parse;
                        int lose = 0;
-                       parse = (struct parse *)0;
-                       status = new_parse (&parse, -1,
-                                           (char *)value -> u.buffer.value,
-                                           value -> u.buffer.len,
+                       parse = NULL;
+                       status = new_parse(&parse, -1,
+                                           (char *) value->u.buffer.value,
+                                           value->u.buffer.len,
                                            "network client", 0);
-                       if (status != ISC_R_SUCCESS)
+                       if (status != ISC_R_SUCCESS || parse == NULL)
                                return status;
                        if (!(parse_executable_statements
                              (&group -> group -> statements, parse, &lose,
index d676c643a9efd4151367190564cf626cd4c238b9..176551d9b39c1e27204b158477c762e1adc0d628 100644 (file)
@@ -52,21 +52,18 @@ isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
        const char *name;
        int eolp;
 {
+       isc_result_t status = ISC_R_SUCCESS;
        struct parse *tmp;
 
        tmp = dmalloc(sizeof(struct parse), MDL);
        if (tmp == NULL) {
-               return ISC_R_NOMEMORY;
+               return (ISC_R_NOMEMORY);
        }
 
        /*
         * We don't need to initialize things to zero here, since 
         * 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->lpos = tmp -> line = 1;
        tmp->cur_line = tmp->line1;
@@ -83,20 +80,30 @@ isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
        } else {
                struct stat sb;
 
-               if (fstat(file, &sb) < 0)
-                       return ISC_R_IOERROR;
+               if (fstat(file, &sb) < 0) {
+                       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,
                                  file, 0);
 
                if (tmp->inbuf == MAP_FAILED) {
-                       return ISC_R_IOERROR;
+                       status = ISC_R_IOERROR;
+                       goto cleanup;
                }
        }
 
        *cfile = tmp;
-       return ISC_R_SUCCESS;
+       return (ISC_R_SUCCESS);
+
+cleanup:
+       dfree(tmp, MDL);
+       return (status);
 }
 
 isc_result_t end_parse (cfile)
index 940435e1a48cbe7ea563b13d4fab99bb04cc8335..a6b1637a86355f7eb34400c2dc9a04947a286b75 100644 (file)
@@ -47,14 +47,17 @@ void read_resolv_conf (parse_time)
        int token;
        struct name_server *sp, *sl, *ns;
        struct domain_search_list *dp, *dl, *nd;
+       isc_result_t status;
 
        if ((file = open (path_resolv_conf, O_RDONLY)) < 0) {
                log_error ("Can't open %s: %m", path_resolv_conf);
                return;
        }
 
-       cfile = (struct parse *)0;
-       new_parse (&cfile, file, (char *)0, 0, path_resolv_conf, 1);
+       cfile = NULL;
+       status = new_parse(&cfile, file, NULL, 0, path_resolv_conf, 1);
+       if (status != ISC_R_SUCCESS || cfile == NULL)
+               return;
 
        do {
                token = next_token (&val, (unsigned *)0, cfile);
index 2121225fe2a89e46151216dbe44dde50fe788cec..1aaaaed20e340d8f3ec147146882f880d908c0e9 100644 (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 (trace_record ())
                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
-       new_parse (&cfile, file, (char *)0, 0, filename, 0);
+       status = new_parse(&cfile, file, NULL, 0, filename, 0);
 #endif
+       if (status != ISC_R_SUCCESS || cfile == NULL)
+               return status;
+
        if (leasep)
                status = lease_file_subparse (cfile);
        else
@@ -181,6 +184,7 @@ void trace_conf_input (trace_type_t *ttype, unsigned len, char *data)
        struct parse *cfile = (struct parse *)0;
        static int postconf_initialized;
        static int leaseconf_initialized;
+       isc_result_t status;
        
        /* Do what's done above, except that we don't have to read in the
           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 (trace_record ())
                trace_write_packet (ttype, len, data, MDL);
-       new_parse (&cfile, -1, fbuf, flen, data, 0);
-       if (ttype == trace_readleases_type)
-               lease_file_subparse (cfile);
-       else
-               conf_file_subparse (cfile, root_group, ROOT_GROUP);
-       end_parse (&cfile);
+
+       status = new_parse(&cfile, -1, fbuf, flen, data, 0);
+       if (status == ISC_R_SUCCESS || cfile != NULL) {
+               if (ttype == trace_readleases_type)
+                       lease_file_subparse (cfile);
+               else
+                       conf_file_subparse (cfile, root_group, ROOT_GROUP);
+               end_parse (&cfile);
+       }
 
        /* Postconfiguration needs to be done after the config file
           has been loaded. */
index 0f17ce41724220b4d1631b0730d11d656f5c3ece..1d60827cf1838140cfe1ccb6d00a5c1d4cdd4365 100644 (file)
@@ -612,20 +612,21 @@ main(int argc, char **argv) {
 
 #if defined (NSUPDATE)
        /* Set up the standard name service updater routine. */
-       parse = (struct parse *)0;
-       status = new_parse (&parse, -1,
-                           std_nsupdate, (sizeof std_nsupdate) - 1,
+       parse = NULL;
+       status = new_parse(&parse, -1, std_nsupdate, sizeof(std_nsupdate) - 1,
                            "standard name service update routine", 0);
        if (status != ISC_R_SUCCESS)
                log_fatal ("can't begin parsing name service updater!");
 
-       lose = 0;
-       if (!(parse_executable_statements
-             (&root_group -> statements, parse, &lose, context_any))) {
-               end_parse (&parse);
-               log_fatal ("can't parse standard name service updater!");
+       if (parse != NULL) {
+               lose = 0;
+               if (!(parse_executable_statements(&root_group->statements,
+                                                 parse, &lose, context_any))) {
+                       end_parse(&parse);
+                       log_fatal("can't parse standard name service updater!");
+               }
+               end_parse(&parse);
        }
-       end_parse (&parse);
 #endif
 
        /* Initialize icmp support... */
@@ -1129,20 +1130,22 @@ void postconf_initialization (int quiet)
                }
 
                /* Set up the standard name service updater routine. */
-               parse = (struct parse *)0;
-               result = new_parse (&parse, -1,
-                                old_nsupdate, (sizeof old_nsupdate) - 1,
-                                "old name service update routine", 0);
+               parse = NULL;
+               result = new_parse(&parse, -1, old_nsupdate,
+                                  sizeof(old_nsupdate) - 1,
+                                  "old name service update routine", 0);
                if (result != ISC_R_SUCCESS)
                        log_fatal ("can't begin parsing old ddns updater!");
 
-               tmp = 0;
-               if (!(parse_executable_statements (e, parse,
-                                                  &tmp, context_any))) {
-                       end_parse (&parse);
-                       log_fatal ("can't parse standard ddns updater!");
+               if (parse != NULL) {
+                       tmp = 0;
+                       if (!(parse_executable_statements(e, parse, &tmp,
+                                                         context_any))) {
+                               end_parse(&parse);
+                               log_fatal("can't parse standard ddns updater!");
+                       }
                }
-               end_parse (&parse);
+               end_parse(&parse);
        }
 #endif
 }
index 96541c292961c746ae6c38badd462b31f5a9c234..4420e81dc74f48c9cc0704ec90f311c7c87a9d52 100644 (file)
@@ -1067,12 +1067,13 @@ isc_result_t dhcp_host_set_value  (omapi_object_t *h,
                        struct parse *parse;
                        int lose = 0;
                        parse = (struct parse *)0;
-                       status = new_parse (&parse, -1,
-                                           (char *)value -> u.buffer.value,
-                                           value -> u.buffer.len,
+                       status = new_parse(&parse, -1,
+                                           (char *) value->u.buffer.value,
+                                           value->u.buffer.len,
                                            "network client", 0);
-                       if (status != ISC_R_SUCCESS)
+                       if (status != ISC_R_SUCCESS || parse == NULL)
                                return status;
+
                        if (!(parse_executable_statements
                              (&host -> group -> statements, parse, &lose,
                               context_any))) {