2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-22 01:49:35 +00:00

dhc6_lease_destroy() and dhc6_ia_destroy() now set lease and IA

pointers to NULL after freeing, to prevent subsequent accesses to freed
memory.  [rt17352]
This commit is contained in:
Evan Hunt 2007-12-08 19:36:00 +00:00
parent 76db44f9d6
commit e32529a528
4 changed files with 56 additions and 38 deletions

View File

@ -54,6 +54,9 @@ suggested fixes to <dhcp-users@isc.org>.
Changes since 4.0.0rc1
- dhc6_lease_destroy() and dhc6_ia_destroy() now set lease and IA pointers
to NULL after freeing, to prevent subsequent accesses to freed memory.
- The DHCPv6 server would not send the preference option unless the
client requested it, via the ORO. This has been fixed, so the DHCPv6
server will always send the preference value if it is configured.

View File

@ -1398,7 +1398,7 @@ parse_client6_lease_statement(struct parse *cfile)
if (!has_ia) {
log_debug("Lease with no IA's discarded from lease db.");
dhc6_lease_destroy(lease, MDL);
dhc6_lease_destroy(&lease, MDL);
return;
}
@ -1415,7 +1415,7 @@ parse_client6_lease_statement(struct parse *cfile)
if (client == NULL) {
parse_warn(cfile, "No matching client state.");
dhc6_lease_destroy(lease, MDL);
dhc6_lease_destroy(&lease, MDL);
return;
}
@ -1429,7 +1429,7 @@ parse_client6_lease_statement(struct parse *cfile)
log_error("Invalid length of DHCPv6 Preference option "
"(%d != 1)", ds.len);
data_string_forget(&ds, MDL);
dhc6_lease_destroy(lease, MDL);
dhc6_lease_destroy(&lease, MDL);
return;
} else
lease->pref = ds.data[0];
@ -1446,12 +1446,12 @@ parse_client6_lease_statement(struct parse *cfile)
(lease->server_id.len == 0)) {
/* This should be impossible... */
log_error("Invalid SERVERID option cache.");
dhc6_lease_destroy(lease, MDL);
dhc6_lease_destroy(&lease, MDL);
return;
}
if (client->active_lease != NULL)
dhc6_lease_destroy(client->active_lease, MDL);
dhc6_lease_destroy(&client->active_lease, MDL);
client->active_lease = lease;
#endif /* defined(DHCPv6) */

View File

@ -43,7 +43,7 @@ static struct dhc6_ia *dhc6_dup_ia(struct dhc6_ia *ia,
const char *file, int line);
static struct dhc6_addr *dhc6_dup_addr(struct dhc6_addr *addr,
const char *file, int line);
static void dhc6_ia_destroy(struct dhc6_ia *ia, const char *file, int line);
static void dhc6_ia_destroy(struct dhc6_ia **src, const char *file, int line);
static isc_result_t dhc6_parse_ia_na(struct dhc6_ia **pia,
struct packet *packet,
struct option_state *options);
@ -387,7 +387,7 @@ dhc6_dup_lease(struct dhc6_lease *lease, const char *file, int line)
*insert_ia = dhc6_dup_ia(ia, file, line);
if (*insert_ia == NULL) {
dhc6_lease_destroy(copy, file, line);
dhc6_lease_destroy(&copy, file, line);
return NULL;
}
@ -418,7 +418,7 @@ dhc6_dup_ia(struct dhc6_ia *ia, const char *file, int line)
*insert_addr = dhc6_dup_addr(addr, file, line);
if (*insert_addr == NULL) {
dhc6_ia_destroy(copy, file, line);
dhc6_ia_destroy(&copy, file, line);
return NULL;
}
@ -488,7 +488,7 @@ dhc6_leaseify(struct packet *packet)
log_error("Invalid length of DHCPv6 Preference option "
"(%d != 1)", ds.len);
data_string_forget(&ds, MDL);
dhc6_lease_destroy(lease, MDL);
dhc6_lease_destroy(&lease, MDL);
return NULL;
} else {
lease->pref = ds.data[0];
@ -505,7 +505,7 @@ dhc6_leaseify(struct packet *packet)
if (dhc6_parse_ia_na(&lease->bindings, packet,
lease->options) != ISC_R_SUCCESS) {
/* Error conditions are logged by the caller. */
dhc6_lease_destroy(lease, MDL);
dhc6_lease_destroy(&lease, MDL);
return NULL;
}
@ -522,7 +522,7 @@ dhc6_leaseify(struct packet *packet)
/* This should be impossible due to validation checks earlier.
*/
log_error("Invalid SERVERID option cache.");
dhc6_lease_destroy(lease, MDL);
dhc6_lease_destroy(&lease, MDL);
return NULL;
} else {
log_debug("RCV: X-- Server ID: %s",
@ -730,15 +730,18 @@ dhc6_parse_addrs(struct dhc6_addr **paddr, struct packet *packet,
return ISC_R_SUCCESS;
}
/* Clean up a lease object and deallocate all its parts. */
/* Clean up a lease object, deallocate all its parts, and set it to NULL. */
void
dhc6_lease_destroy(struct dhc6_lease *lease, const char *file, int line)
dhc6_lease_destroy(struct dhc6_lease **src, const char *file, int line)
{
struct dhc6_ia *ia, *nia;
struct dhc6_lease *lease;
/* no-op */
if (lease == NULL)
if (src == NULL || *src == NULL) {
log_error("Attempt to destroy null lease.");
return;
}
lease = *src;
if (lease->server_id.len != 0)
data_string_forget(&lease->server_id, file, line);
@ -746,20 +749,31 @@ dhc6_lease_destroy(struct dhc6_lease *lease, const char *file, int line)
for (ia = lease->bindings ; ia != NULL ; ia = nia) {
nia = ia->next;
dhc6_ia_destroy(ia, file, line);
dhc6_ia_destroy(&ia, file, line);
}
if (lease->options != NULL)
option_state_dereference(&lease->options, file, line);
dfree(lease, file, line);
*src = NULL;
}
/* Traverse the addresses list, and destroy their contents. */
/*
* Traverse the addresses list, and destroy their contents, and NULL the
* list pointer.
*/
static void
dhc6_ia_destroy(struct dhc6_ia *ia, const char *file, int line)
dhc6_ia_destroy(struct dhc6_ia **src, const char *file, int line)
{
struct dhc6_addr *addr, *naddr;
struct dhc6_ia *ia;
if (src == NULL || *src == NULL) {
log_error("Attempt to destroy null IA.");
return;
}
is = *src;
for (addr = ia->addrs ; addr != NULL ; addr = naddr) {
naddr = addr->next;
@ -774,6 +788,7 @@ dhc6_ia_destroy(struct dhc6_ia *ia, const char *file, int line)
option_state_dereference(&ia->options, file, line);
dfree(ia, file, line);
*src = NULL;
}
/* For a given lease, insert it into the tail of the lease list. Upon
@ -787,7 +802,7 @@ insert_lease(struct dhc6_lease **head, struct dhc6_lease *new)
memcmp((*head)->server_id.data, new->server_id.data,
new->server_id.len) == 0) {
new->next = (*head)->next;
dhc6_lease_destroy(*head, MDL);
dhc6_lease_destroy(head, MDL);
break;
}
@ -1314,7 +1329,7 @@ status_log(int code, const char *scope, const char *additional, int len)
switch(code) {
case STATUS_Success:
msg = "Succes";
msg = "Success";
break;
case STATUS_UnspecFail:
@ -1493,7 +1508,7 @@ dhc6_select_action(struct client_state *client, isc_result_t rval,
default:
case STATUS_UnspecFail:
if (client->advertised_leases != NULL) {
dhc6_lease_destroy(client->selected_lease, MDL);
dhc6_lease_destroy(&client->selected_lease, MDL);
client->selected_lease = NULL;
start_selecting6(client);
@ -1513,7 +1528,7 @@ dhc6_select_action(struct client_state *client, isc_result_t rval,
if (client->selected_lease == NULL)
log_fatal("Impossible case at %s:%d.", MDL);
dhc6_lease_destroy(client->selected_lease, MDL);
dhc6_lease_destroy(&client->selected_lease, MDL);
client->selected_lease = NULL;
if (client->advertised_leases != NULL)
@ -1534,19 +1549,19 @@ dhc6_select_action(struct client_state *client, isc_result_t rval,
if (client->active_lease == NULL)
log_fatal("Impossible case at %s:%d.", MDL);
dhc6_lease_destroy(client->active_lease, MDL);
dhc6_lease_destroy(&client->active_lease, MDL);
} else {
if (client->selected_lease == NULL)
log_fatal("Impossible case at %s:%d.", MDL);
dhc6_lease_destroy(client->selected_lease, MDL);
dhc6_lease_destroy(&client->selected_lease, MDL);
client->selected_lease = NULL;
while (client->advertised_leases != NULL) {
lease = client->advertised_leases;
client->advertised_leases = lease->next;
dhc6_lease_destroy(lease, MDL);
dhc6_lease_destroy(&lease, MDL);
}
}
@ -1748,7 +1763,7 @@ dhc6_check_reply(struct client_state *client, struct dhc6_lease *new)
"Trying other servers.",
nscore, sscore);
dhc6_lease_destroy(client->selected_lease, MDL);
dhc6_lease_destroy(&client->selected_lease, MDL);
client->selected_lease = NULL;
start_selecting6(client);
@ -1807,7 +1822,7 @@ init_handler(struct packet *packet, struct client_state *client)
if (dhc6_check_advertise(lease) != ISC_R_SUCCESS) {
log_debug("PRC: Lease failed to satisfy.");
dhc6_lease_destroy(lease, MDL);
dhc6_lease_destroy(&lease, MDL);
return;
}
@ -2030,7 +2045,7 @@ do_select6(void *input)
lease->server_id.data, 56));
/* Get rid of the lease that timed/counted out. */
dhc6_lease_destroy(lease, MDL);
dhc6_lease_destroy(&lease, MDL);
client->selected_lease = NULL;
/* If there are more leases great. If not, get more. */
@ -2298,7 +2313,7 @@ reply_handler(struct packet *packet, struct client_state *client)
check_status = dhc6_check_reply(client, lease);
if (check_status != ISC_R_SUCCESS) {
dhc6_lease_destroy(lease, MDL);
dhc6_lease_destroy(&lease, MDL);
/* If no action was taken, but there is an error, then
* we wait for a retransmission.
@ -2320,7 +2335,7 @@ reply_handler(struct packet *packet, struct client_state *client)
return;
if (client->selected_lease != NULL) {
dhc6_lease_destroy(client->selected_lease, MDL);
dhc6_lease_destroy(&client->selected_lease, MDL);
client->selected_lease = NULL;
}
@ -2329,7 +2344,7 @@ reply_handler(struct packet *packet, struct client_state *client)
if (client->active_lease == NULL)
log_fatal("Impossible condition at %s:%d.", MDL);
dhc6_lease_destroy(client->active_lease, MDL);
dhc6_lease_destroy(&client->active_lease, MDL);
client->active_lease = NULL;
return;
}
@ -2341,7 +2356,7 @@ reply_handler(struct packet *packet, struct client_state *client)
if (client->active_lease == NULL)
log_fatal("Impossible condition at %s:%d.", MDL);
dhc6_lease_destroy(lease, MDL);
dhc6_lease_destroy(&lease, MDL);
start_bound(client);
return;
}
@ -2353,7 +2368,7 @@ reply_handler(struct packet *packet, struct client_state *client)
/* Cleanup if a previous attempt to go bound failed. */
if (client->old_lease != NULL) {
dhc6_lease_destroy(client->old_lease, MDL);
dhc6_lease_destroy(&client->old_lease, MDL);
client->old_lease = NULL;
}
@ -2367,7 +2382,7 @@ reply_handler(struct packet *packet, struct client_state *client)
lease = client->advertised_leases;
client->advertised_leases = lease->next;
dhc6_lease_destroy(lease, MDL);
dhc6_lease_destroy(&lease, MDL);
}
start_bound(client);
@ -2547,7 +2562,7 @@ dhc6_check_times(struct client_state *client)
* schedule a future request (using 4-pkt info-request model).
*/
if (has_addrs == ISC_FALSE) {
dhc6_lease_destroy(client->active_lease, MDL);
dhc6_lease_destroy(&client->active_lease, MDL);
client->active_lease = NULL;
/* Go back to the beginning. */
@ -2822,7 +2837,7 @@ start_bound(struct client_state *client)
go_daemon();
if (client->old_lease != NULL) {
dhc6_lease_destroy(client->old_lease, MDL);
dhc6_lease_destroy(&client->old_lease, MDL);
client->old_lease = NULL;
}
@ -3131,7 +3146,7 @@ do_expire(void *input)
log_info("PRC: Bound lease is devoid of active addresses."
" Re-initializing.");
dhc6_lease_destroy(lease, MDL);
dhc6_lease_destroy(&lease, MDL);
client->active_lease = NULL;
start_init6(client);

View File

@ -2463,7 +2463,7 @@ void dhcpv6_client_assignments(void);
/* dhc6.c */
void form_duid(struct data_string *duid, const char *file, int line);
void dhc6_lease_destroy(struct dhc6_lease *lease, const char *file, int line);
void dhc6_lease_destroy(struct dhc6_lease **src, const char *file, int line);
void start_init6(struct client_state *client);
void start_confirm6(struct client_state *client);
void start_release6(struct client_state *client);