]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[#57] Fixed reference leaks.
authorThomas Markwalder <tmark@isc.org>
Wed, 11 Dec 2019 11:40:48 +0000 (11:40 +0000)
committerThomas Markwalder <tmark@isc.org>
Wed, 11 Dec 2019 13:55:14 +0000 (08:55 -0500)
    Merges in !39, which applied changes from #57/master.

13 files changed:
RELNOTES
client/dhc6.c
client/dhclient.c
common/dns.c
common/execute.c
common/options.c
relay/dhcrelay.c
server/class.c
server/confpars.c
server/dhcp.c
server/dhcpleasequery.c
server/dhcpv6.c
server/mdb6.c

index 1b3ba2208bec7a49160f1e47cf3075eed9a6432d..534ce2f8d81b9c2cccb867c14ba98480acf3c6ab 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -87,6 +87,9 @@ dhcp-users@lists.isc.org.
   for reporting this issue.
   [Gitlab #2]
 
+- Corrected a number of reference counter and zero-length buffer leaks.
+  [Gitlab #57]
+
                        Changes since 4.1-ESV-R15
 
 - Corrected dhclient command line parsing for --dad-wait-time that causes
index f008ee17063eefafcc7c59b8a0a4b76386ccd88d..4bbe2e746aab31a107b52be7cedb5c5cb2a665a0 100644 (file)
@@ -867,8 +867,7 @@ dhc6_parse_ia_na(struct dhc6_ia **pia, struct packet *packet,
                } else {
                        log_error("Invalid IA_NA option cache.");
                        dfree(ia, MDL);
-                       if (ds.len != 0)
-                               data_string_forget(&ds, MDL);
+                       data_string_forget(&ds, MDL);
                        return ISC_R_UNEXPECTED;
                }
        }
@@ -970,8 +969,7 @@ dhc6_parse_ia_ta(struct dhc6_ia **pia, struct packet *packet,
                } else {
                        log_error("Invalid IA_TA option cache.");
                        dfree(ia, MDL);
-                       if (ds.len != 0)
-                               data_string_forget(&ds, MDL);
+                       data_string_forget(&ds, MDL);
                        return ISC_R_UNEXPECTED;
                }
        }
@@ -1093,8 +1091,7 @@ dhc6_parse_ia_pd(struct dhc6_ia **pia, struct packet *packet,
                } else {
                        log_error("Invalid IA_PD option cache.");
                        dfree(ia, MDL);
-                       if (ds.len != 0)
-                               data_string_forget(&ds, MDL);
+                       data_string_forget(&ds, MDL);
                        return ISC_R_UNEXPECTED;
                }
        }
@@ -1209,8 +1206,7 @@ dhc6_parse_addrs(struct dhc6_addr **paddr, struct packet *packet,
                } else {
                        log_error("Invalid IAADDR option cache.");
                        dfree(addr, MDL);
-                       if (ds.len != 0)
-                               data_string_forget(&ds, MDL);
+                       data_string_forget(&ds, MDL);
                        return ISC_R_UNEXPECTED;
                }
        }
@@ -1334,8 +1330,7 @@ dhc6_parse_prefixes(struct dhc6_addr **ppfx, struct packet *packet,
                } else {
                        log_error("Invalid IAPREFIX option cache.");
                        dfree(pfx, MDL);
-                       if (ds.len != 0)
-                               data_string_forget(&ds, MDL);
+                       data_string_forget(&ds, MDL);
                        return ISC_R_UNEXPECTED;
                }
        }
@@ -1357,9 +1352,7 @@ dhc6_lease_destroy(struct dhc6_lease **src, const char *file, int line)
        }
        lease = *src;
 
-       if (lease->server_id.len != 0)
-               data_string_forget(&lease->server_id, file, line);
-
+       data_string_forget(&lease->server_id, file, line);
        for (ia = lease->bindings ; ia != NULL ; ia = nia) {
                nia = ia->next;
 
index 7d560d61d07778d7b4d50e680971e1b56e10db79..5015388cc18c68b978da730c2f13a9e5998f045e 100644 (file)
@@ -3248,9 +3248,10 @@ void client_option_envadd (struct option_cache *oc,
                                                  "option - discarded",
                                                  name);
                                }
-                               data_string_forget (&data, MDL);
                        }
                }
+
+               data_string_forget (&data, MDL);
        }
 }
 
index 51e9c75c3db3f680a4270bf86532e42df9eb98c0..870eaa26044eb43ce839f2212ce89c46681b882f 100644 (file)
@@ -400,15 +400,19 @@ void cache_found_zone (ns_class class,
        /* See if there's already such a zone. */
        if (dns_zone_lookup (&zone, zname) == ISC_R_SUCCESS) {
                /* If it's not a dynamic zone, leave it alone. */
-               if (!zone -> timeout)
+               if (!zone -> timeout) {
+                       dns_zone_dereference (&zone, MDL);
                        return;
+               }
+
                /* Address may have changed, so just blow it away. */
                if (zone -> primary)
                        option_cache_dereference (&zone -> primary, MDL);
                if (zone -> secondary)
                        option_cache_dereference (&zone -> secondary, MDL);
-       } else if (!dns_zone_allocate (&zone, MDL))
+       } else if (!dns_zone_allocate (&zone, MDL)) {
                return;
+       }
 
        if (!zone -> name) {
                zone -> name =
@@ -445,6 +449,7 @@ void cache_found_zone (ns_class class,
        zone -> primary -> data.len = naddrs * sizeof *addrs;
 
        enter_dns_zone (zone);
+       dns_zone_dereference (&zone, MDL);
 }
 
 /* Have to use TXT records for now. */
index bd21fe0425a4050db9c2a758d54afffefde3d365..bb8fd92d383d030d09187adec8d3b9a56aed272c 100644 (file)
@@ -71,8 +71,11 @@ int execute_statements (result, packet, lease, client_state,
 #if defined (DEBUG_EXPRESSIONS)
                        log_debug ("exec: statements returns %d", status);
 #endif
-                       if (!status)
+                       if (!status) {
+                               executable_statement_dereference (&r, MDL);
                                return 0;
+                       }
+
                        break;
 
                      case on_statement:
@@ -134,6 +137,8 @@ int execute_statements (result, packet, lease, client_state,
                                       in_options, out_options, scope, e))) {
                                        executable_statement_dereference
                                                (&e, MDL);
+                                       executable_statement_dereference
+                                               (&r, MDL);
                                        return 0;
                                }
                                executable_statement_dereference (&e, MDL);
@@ -162,8 +167,10 @@ int execute_statements (result, packet, lease, client_state,
                        if (!execute_statements
                            (result, packet, lease, client_state,
                             in_options, out_options, scope,
-                            rc ? r -> data.ie.tc : r -> data.ie.fc))
+                            rc ? r -> data.ie.tc : r -> data.ie.fc)) {
+                               executable_statement_dereference (&r, MDL);
                                return 0;
+                       }
                        break;
 
                      case eval_statement:
@@ -285,6 +292,7 @@ int execute_statements (result, packet, lease, client_state,
 #if defined (DEBUG_EXPRESSIONS)
                        log_debug ("exec: break");
 #endif
+                       executable_statement_dereference (&r, MDL);
                        return 1;
 
                      case supersede_option_statement:
index 09723c600f2f483fbd81dd21dffffc1a97b29f7d..b9a525c050c117fff92a804df1c04c87bd7ff7d2 100644 (file)
@@ -220,6 +220,7 @@ int parse_option_buffer (options, buffer, length, universe)
                                        log_error("parse_option_buffer: "
                                                  "No memory.");
                                        buffer_dereference(&bp, MDL);
+                                       option_dereference(&option, MDL);
                                        return 0;
                                }
                                /* Copy old option to new data object. */
@@ -245,6 +246,7 @@ int parse_option_buffer (options, buffer, length, universe)
                                        log_error("parse_option_buffer: "
                                                  "No memory.");
                                        buffer_dereference(&bp, MDL);
+                                       option_dereference(&option, MDL);
                                        return 0;
                                }
 
@@ -1382,8 +1384,9 @@ store_options(int *ocount,
                                (option_space_encapsulate
                                 (&encapsulation, packet, lease, client_state,
                                  in_options, cfg_options, scope, &name));
-                       data_string_forget (&name, MDL);
                    }
+
+                   data_string_forget (&name, MDL);
                }
            }
 
@@ -3388,8 +3391,7 @@ int fqdn_option_space_encapsulate (result, packet, lease, client_state,
        }
       exit:
        for (i = 1; i <= FQDN_SUBOPTION_COUNT; i++) {
-               if (results [i].len)
-                       data_string_forget (&results [i], MDL);
+               data_string_forget (&results[i], MDL);
        }
        buffer_dereference (&bp, MDL);
        if (!status)
@@ -3548,8 +3550,7 @@ fqdn6_option_space_encapsulate(struct data_string *result,
 
       exit:
        for (i = 1 ; i <= FQDN_SUBOPTION_COUNT ; i++) {
-               if (results[i].len)
-                       data_string_forget(&results[i], MDL);
+               data_string_forget(&results[i], MDL);
        }
 
        return rval;
index 14f8230d2f3e0707d5ee600f3b15a5baa92118a5..64238a305eaa1eed8de0f4835756371f5d8645f3 100644 (file)
@@ -1603,7 +1603,7 @@ process_down6(struct packet *packet) {
                                   &global_scope, oc, MDL) ||
            (relay_msg.len < offsetof(struct dhcpv6_packet, options))) {
                log_error("Can't evaluate relay-msg.");
-               return;
+               goto cleanup;
        }
        msg = (const struct dhcpv6_packet *) relay_msg.data;
 
index 971f3ab20be0c1ebe334d140614cbe814dcafc62..c19cdc18c3d0199e2e8be2589d0b28d637a1b0d8 100644 (file)
@@ -177,7 +177,6 @@ int check_collection (packet, lease, collection)
                                }
                                data_string_copy (&nc -> hash_string, &data,
                                                  MDL);
-                               data_string_forget (&data, MDL);
                                if (!class -> hash)
                                    class_new_hash(&class->hash,
                                                   SCLASS_HASH_SIZE, MDL);
@@ -189,6 +188,8 @@ int check_collection (packet, lease, collection)
                                classify (packet, nc);
                                class_dereference (&nc, MDL);
                        }
+
+                       data_string_forget (&data, MDL);
                }
        }
        return matched;
index ef411b6f7717a521c807a6dcf2822249e643123e..1841bd781e84642c31b5bea23e37f48a1043260f 100644 (file)
@@ -777,8 +777,11 @@ int parse_statement (cfile, group, type, host_decl, declaration)
                        et = (struct executable_statement *)0;
                        if (!parse_option_statement
                                (&et, cfile, 1, option,
-                                supersede_option_statement))
+                                supersede_option_statement)) {
+                               option_dereference(&option, MDL);
                                return declaration;
+                               }
+
                        option_dereference(&option, MDL);
                        goto insert_statement;
                } else
@@ -2652,6 +2655,7 @@ void parse_subnet_declaration (cfile, share)
        if (token != NETMASK) {
                parse_warn (cfile, "Expecting netmask");
                skip_to_semi (cfile);
+               subnet_dereference (&subnet, MDL);
                return;
        }
 
@@ -2747,6 +2751,7 @@ parse_subnet6_declaration(struct parse *cfile, struct shared_network *share) {
        if (token != SLASH) {
                parse_warn(cfile, "Expecting a '/'.");
                skip_to_semi(cfile);
+               subnet_dereference(&subnet, MDL);
                return;
        }
 
@@ -2754,6 +2759,7 @@ parse_subnet6_declaration(struct parse *cfile, struct shared_network *share) {
        if (token != NUMBER) {
                parse_warn(cfile, "Expecting a number.");
                skip_to_semi(cfile);
+               subnet_dereference(&subnet, MDL);
                return;
        }
 
@@ -2763,12 +2769,14 @@ parse_subnet6_declaration(struct parse *cfile, struct shared_network *share) {
            (*endp != '\0')) {
                parse_warn(cfile, "Expecting a number between 0 and 128.");
                skip_to_semi(cfile);
+               subnet_dereference(&subnet, MDL);
                return;
        }
 
        if (!is_cidr_mask_valid(&subnet->net, subnet->prefix_len)) {
                parse_warn(cfile, "New subnet mask too short.");
                skip_to_semi(cfile);
+               subnet_dereference(&subnet, MDL);
                return;
        }
 
index 9fd17e2d940f71f1aa004c6bf7b18c6c9296156f..a7693cdab868401c77ae04e7ee3706407c1ee5d6 100644 (file)
@@ -1204,8 +1204,11 @@ void dhcpinform (packet, ms_nulltp)
                                           MDL)) {
                        log_error ("unknown option space %s.", d1.data);
                        option_state_dereference (&options, MDL);
-                       if (subnet)
+                       if (subnet) {
                                subnet_dereference (&subnet, MDL);
+                       }
+
+                       data_string_forget (&d1, MDL);
                        return;
                }
 
@@ -2856,6 +2859,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
                                           (const char *)d1.data, d1.len,
                                           MDL)) {
                        log_error ("unknown option space %s.", d1.data);
+                       data_string_forget (&d1, MDL);
                        return;
                }
 
@@ -4361,6 +4365,7 @@ int locate_network (packet)
                        data_string_forget (&data, MDL);
                        return 0;
                }
+
                ia.len = 4;
                memcpy (ia.iabuf, data.data, 4);
                data_string_forget (&data, MDL);
index 5ffd5c4f543428dc24c9a6637ea708e53ee62bc6..5fc40276b4656feeecbf66e1b3130186da0819e5 100644 (file)
@@ -868,15 +868,9 @@ valid_query_msg(struct lq6_state *lq) {
 
 exit:
        if (!ret_val) {
-               if (lq->client_id.len > 0) {
-                       data_string_forget(&lq->client_id, MDL);
-               }
-               if (lq->server_id.len > 0) {
-                       data_string_forget(&lq->server_id, MDL);
-               }
-               if (lq->lq_query.len > 0) {
-                       data_string_forget(&lq->lq_query, MDL);
-               }
+               data_string_forget(&lq->client_id, MDL);
+               data_string_forget(&lq->server_id, MDL);
+               data_string_forget(&lq->lq_query, MDL);
        }
        return ret_val;
 }
index 49b55c74fb32799683655f197b55ec7a66ab8268..ffd5e84560e077dbbcc900e03a35bab179bf93f5 100644 (file)
@@ -488,13 +488,9 @@ valid_client_msg(struct packet *packet, struct data_string *client_id) {
        ret_val = 1;
 
 exit:
-       if (data.len > 0) {
-               data_string_forget(&data, MDL);
-       }
+       data_string_forget(&data, MDL);
        if (!ret_val) {
-               if (client_id->len > 0) {
-                       data_string_forget(client_id, MDL);
-               }
+               data_string_forget(client_id, MDL);
        }
        return ret_val;
 }
@@ -579,12 +575,8 @@ valid_client_resp(struct packet *packet,
 
 exit:
        if (!ret_val) {
-               if (server_id->len > 0) {
-                       data_string_forget(server_id, MDL);
-               }
-               if (client_id->len > 0) {
-                       data_string_forget(client_id, MDL);
-               }
+               data_string_forget(server_id, MDL);
+               data_string_forget(client_id, MDL);
        }
        return ret_val;
 }
@@ -696,9 +688,7 @@ valid_client_info_req(struct packet *packet, struct data_string *server_id) {
 
 exit:
        if (!ret_val) {
-               if (server_id->len > 0) {
-                       data_string_forget(server_id, MDL);
-               }
+               data_string_forget(server_id, MDL);
        }
        return ret_val;
 }
index f96f7dd169dad5fa98438196a5238277f559f21f..c914986c3746e9be18892110068934beaa8b233b 100644 (file)
@@ -864,9 +864,11 @@ create_lease6(struct ipv6_pool *pool, struct iasubopt **addr,
                case D6O_IA_PD:
                        /* prefix */
                        log_error("create_lease6: prefix pool.");
+                       data_string_forget(&ds, MDL);
                        return ISC_R_INVALIDARG;
                default:
                        log_error("create_lease6: untyped pool.");
+                       data_string_forget(&ds, MDL);
                        return ISC_R_INVALIDARG;
                }