summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Markwalder <tmark@isc.org>2019-12-11 11:40:48 +0000
committerThomas Markwalder <tmark@isc.org>2019-12-11 08:55:14 -0500
commit9bc0f5d1d227218efa5a8415e4e57c7304067d7d (patch)
tree4c5a75d6ea5c3e7f5959a53a1b536b160ed4a434
parent2bf9c0e7f0594687be090478ddcdb4fe6f7cd377 (diff)
downloadisc-dhcp-9bc0f5d1d227218efa5a8415e4e57c7304067d7d.tar.gz
[#57] Fixed reference leaks.
Merges in !39, which applied changes from #57/master.
-rw-r--r--RELNOTES3
-rw-r--r--client/dhc6.c19
-rw-r--r--client/dhclient.c3
-rw-r--r--common/dns.c9
-rw-r--r--common/execute.c12
-rw-r--r--common/options.c11
-rw-r--r--relay/dhcrelay.c2
-rw-r--r--server/class.c3
-rw-r--r--server/confpars.c10
-rw-r--r--server/dhcp.c7
-rw-r--r--server/dhcpleasequery.c12
-rw-r--r--server/dhcpv6.c20
-rw-r--r--server/mdb6.c2
13 files changed, 62 insertions, 51 deletions
diff --git a/RELNOTES b/RELNOTES
index 1b3ba220..534ce2f8 100644
--- 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
diff --git a/client/dhc6.c b/client/dhc6.c
index f008ee17..4bbe2e74 100644
--- a/client/dhc6.c
+++ b/client/dhc6.c
@@ -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;
diff --git a/client/dhclient.c b/client/dhclient.c
index 7d560d61..5015388c 100644
--- a/client/dhclient.c
+++ b/client/dhclient.c
@@ -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);
}
}
diff --git a/common/dns.c b/common/dns.c
index 51e9c75c..870eaa26 100644
--- a/common/dns.c
+++ b/common/dns.c
@@ -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. */
diff --git a/common/execute.c b/common/execute.c
index bd21fe04..bb8fd92d 100644
--- a/common/execute.c
+++ b/common/execute.c
@@ -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:
diff --git a/common/options.c b/common/options.c
index 09723c60..b9a525c0 100644
--- a/common/options.c
+++ b/common/options.c
@@ -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;
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
index 14f8230d..64238a30 100644
--- a/relay/dhcrelay.c
+++ b/relay/dhcrelay.c
@@ -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;
diff --git a/server/class.c b/server/class.c
index 971f3ab2..c19cdc18 100644
--- a/server/class.c
+++ b/server/class.c
@@ -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;
diff --git a/server/confpars.c b/server/confpars.c
index ef411b6f..1841bd78 100644
--- a/server/confpars.c
+++ b/server/confpars.c
@@ -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;
}
diff --git a/server/dhcp.c b/server/dhcp.c
index 9fd17e2d..a7693cda 100644
--- a/server/dhcp.c
+++ b/server/dhcp.c
@@ -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);
diff --git a/server/dhcpleasequery.c b/server/dhcpleasequery.c
index 5ffd5c4f..5fc40276 100644
--- a/server/dhcpleasequery.c
+++ b/server/dhcpleasequery.c
@@ -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;
}
diff --git a/server/dhcpv6.c b/server/dhcpv6.c
index 49b55c74..ffd5e845 100644
--- a/server/dhcpv6.c
+++ b/server/dhcpv6.c
@@ -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;
}
diff --git a/server/mdb6.c b/server/mdb6.c
index f96f7dd1..c914986c 100644
--- a/server/mdb6.c
+++ b/server/mdb6.c
@@ -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;
}