mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-22 09:57:20 +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:
parent
76db44f9d6
commit
e32529a528
3
RELNOTES
3
RELNOTES
@ -54,6 +54,9 @@ suggested fixes to <dhcp-users@isc.org>.
|
|||||||
|
|
||||||
Changes since 4.0.0rc1
|
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
|
- The DHCPv6 server would not send the preference option unless the
|
||||||
client requested it, via the ORO. This has been fixed, so the DHCPv6
|
client requested it, via the ORO. This has been fixed, so the DHCPv6
|
||||||
server will always send the preference value if it is configured.
|
server will always send the preference value if it is configured.
|
||||||
|
@ -1398,7 +1398,7 @@ parse_client6_lease_statement(struct parse *cfile)
|
|||||||
|
|
||||||
if (!has_ia) {
|
if (!has_ia) {
|
||||||
log_debug("Lease with no IA's discarded from lease db.");
|
log_debug("Lease with no IA's discarded from lease db.");
|
||||||
dhc6_lease_destroy(lease, MDL);
|
dhc6_lease_destroy(&lease, MDL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1415,7 +1415,7 @@ parse_client6_lease_statement(struct parse *cfile)
|
|||||||
|
|
||||||
if (client == NULL) {
|
if (client == NULL) {
|
||||||
parse_warn(cfile, "No matching client state.");
|
parse_warn(cfile, "No matching client state.");
|
||||||
dhc6_lease_destroy(lease, MDL);
|
dhc6_lease_destroy(&lease, MDL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1429,7 +1429,7 @@ parse_client6_lease_statement(struct parse *cfile)
|
|||||||
log_error("Invalid length of DHCPv6 Preference option "
|
log_error("Invalid length of DHCPv6 Preference option "
|
||||||
"(%d != 1)", ds.len);
|
"(%d != 1)", ds.len);
|
||||||
data_string_forget(&ds, MDL);
|
data_string_forget(&ds, MDL);
|
||||||
dhc6_lease_destroy(lease, MDL);
|
dhc6_lease_destroy(&lease, MDL);
|
||||||
return;
|
return;
|
||||||
} else
|
} else
|
||||||
lease->pref = ds.data[0];
|
lease->pref = ds.data[0];
|
||||||
@ -1446,12 +1446,12 @@ parse_client6_lease_statement(struct parse *cfile)
|
|||||||
(lease->server_id.len == 0)) {
|
(lease->server_id.len == 0)) {
|
||||||
/* This should be impossible... */
|
/* This should be impossible... */
|
||||||
log_error("Invalid SERVERID option cache.");
|
log_error("Invalid SERVERID option cache.");
|
||||||
dhc6_lease_destroy(lease, MDL);
|
dhc6_lease_destroy(&lease, MDL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->active_lease != NULL)
|
if (client->active_lease != NULL)
|
||||||
dhc6_lease_destroy(client->active_lease, MDL);
|
dhc6_lease_destroy(&client->active_lease, MDL);
|
||||||
|
|
||||||
client->active_lease = lease;
|
client->active_lease = lease;
|
||||||
#endif /* defined(DHCPv6) */
|
#endif /* defined(DHCPv6) */
|
||||||
|
@ -43,7 +43,7 @@ static struct dhc6_ia *dhc6_dup_ia(struct dhc6_ia *ia,
|
|||||||
const char *file, int line);
|
const char *file, int line);
|
||||||
static struct dhc6_addr *dhc6_dup_addr(struct dhc6_addr *addr,
|
static struct dhc6_addr *dhc6_dup_addr(struct dhc6_addr *addr,
|
||||||
const char *file, int line);
|
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,
|
static isc_result_t dhc6_parse_ia_na(struct dhc6_ia **pia,
|
||||||
struct packet *packet,
|
struct packet *packet,
|
||||||
struct option_state *options);
|
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);
|
*insert_ia = dhc6_dup_ia(ia, file, line);
|
||||||
|
|
||||||
if (*insert_ia == NULL) {
|
if (*insert_ia == NULL) {
|
||||||
dhc6_lease_destroy(copy, file, line);
|
dhc6_lease_destroy(©, file, line);
|
||||||
return NULL;
|
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);
|
*insert_addr = dhc6_dup_addr(addr, file, line);
|
||||||
|
|
||||||
if (*insert_addr == NULL) {
|
if (*insert_addr == NULL) {
|
||||||
dhc6_ia_destroy(copy, file, line);
|
dhc6_ia_destroy(©, file, line);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,7 +488,7 @@ dhc6_leaseify(struct packet *packet)
|
|||||||
log_error("Invalid length of DHCPv6 Preference option "
|
log_error("Invalid length of DHCPv6 Preference option "
|
||||||
"(%d != 1)", ds.len);
|
"(%d != 1)", ds.len);
|
||||||
data_string_forget(&ds, MDL);
|
data_string_forget(&ds, MDL);
|
||||||
dhc6_lease_destroy(lease, MDL);
|
dhc6_lease_destroy(&lease, MDL);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
lease->pref = ds.data[0];
|
lease->pref = ds.data[0];
|
||||||
@ -505,7 +505,7 @@ dhc6_leaseify(struct packet *packet)
|
|||||||
if (dhc6_parse_ia_na(&lease->bindings, packet,
|
if (dhc6_parse_ia_na(&lease->bindings, packet,
|
||||||
lease->options) != ISC_R_SUCCESS) {
|
lease->options) != ISC_R_SUCCESS) {
|
||||||
/* Error conditions are logged by the caller. */
|
/* Error conditions are logged by the caller. */
|
||||||
dhc6_lease_destroy(lease, MDL);
|
dhc6_lease_destroy(&lease, MDL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,7 +522,7 @@ dhc6_leaseify(struct packet *packet)
|
|||||||
/* This should be impossible due to validation checks earlier.
|
/* This should be impossible due to validation checks earlier.
|
||||||
*/
|
*/
|
||||||
log_error("Invalid SERVERID option cache.");
|
log_error("Invalid SERVERID option cache.");
|
||||||
dhc6_lease_destroy(lease, MDL);
|
dhc6_lease_destroy(&lease, MDL);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
log_debug("RCV: X-- Server ID: %s",
|
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;
|
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
|
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_ia *ia, *nia;
|
||||||
|
struct dhc6_lease *lease;
|
||||||
|
|
||||||
/* no-op */
|
if (src == NULL || *src == NULL) {
|
||||||
if (lease == NULL)
|
log_error("Attempt to destroy null lease.");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
lease = *src;
|
||||||
|
|
||||||
if (lease->server_id.len != 0)
|
if (lease->server_id.len != 0)
|
||||||
data_string_forget(&lease->server_id, file, line);
|
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) {
|
for (ia = lease->bindings ; ia != NULL ; ia = nia) {
|
||||||
nia = ia->next;
|
nia = ia->next;
|
||||||
|
|
||||||
dhc6_ia_destroy(ia, file, line);
|
dhc6_ia_destroy(&ia, file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lease->options != NULL)
|
if (lease->options != NULL)
|
||||||
option_state_dereference(&lease->options, file, line);
|
option_state_dereference(&lease->options, file, line);
|
||||||
|
|
||||||
dfree(lease, 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
|
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_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) {
|
for (addr = ia->addrs ; addr != NULL ; addr = naddr) {
|
||||||
naddr = addr->next;
|
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);
|
option_state_dereference(&ia->options, file, line);
|
||||||
|
|
||||||
dfree(ia, file, line);
|
dfree(ia, file, line);
|
||||||
|
*src = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For a given lease, insert it into the tail of the lease list. Upon
|
/* 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,
|
memcmp((*head)->server_id.data, new->server_id.data,
|
||||||
new->server_id.len) == 0) {
|
new->server_id.len) == 0) {
|
||||||
new->next = (*head)->next;
|
new->next = (*head)->next;
|
||||||
dhc6_lease_destroy(*head, MDL);
|
dhc6_lease_destroy(head, MDL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1314,7 +1329,7 @@ status_log(int code, const char *scope, const char *additional, int len)
|
|||||||
|
|
||||||
switch(code) {
|
switch(code) {
|
||||||
case STATUS_Success:
|
case STATUS_Success:
|
||||||
msg = "Succes";
|
msg = "Success";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATUS_UnspecFail:
|
case STATUS_UnspecFail:
|
||||||
@ -1493,7 +1508,7 @@ dhc6_select_action(struct client_state *client, isc_result_t rval,
|
|||||||
default:
|
default:
|
||||||
case STATUS_UnspecFail:
|
case STATUS_UnspecFail:
|
||||||
if (client->advertised_leases != NULL) {
|
if (client->advertised_leases != NULL) {
|
||||||
dhc6_lease_destroy(client->selected_lease, MDL);
|
dhc6_lease_destroy(&client->selected_lease, MDL);
|
||||||
client->selected_lease = NULL;
|
client->selected_lease = NULL;
|
||||||
|
|
||||||
start_selecting6(client);
|
start_selecting6(client);
|
||||||
@ -1513,7 +1528,7 @@ dhc6_select_action(struct client_state *client, isc_result_t rval,
|
|||||||
if (client->selected_lease == NULL)
|
if (client->selected_lease == NULL)
|
||||||
log_fatal("Impossible case at %s:%d.", MDL);
|
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;
|
client->selected_lease = NULL;
|
||||||
|
|
||||||
if (client->advertised_leases != 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)
|
if (client->active_lease == NULL)
|
||||||
log_fatal("Impossible case at %s:%d.", MDL);
|
log_fatal("Impossible case at %s:%d.", MDL);
|
||||||
|
|
||||||
dhc6_lease_destroy(client->active_lease, MDL);
|
dhc6_lease_destroy(&client->active_lease, MDL);
|
||||||
} else {
|
} else {
|
||||||
if (client->selected_lease == NULL)
|
if (client->selected_lease == NULL)
|
||||||
log_fatal("Impossible case at %s:%d.", MDL);
|
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;
|
client->selected_lease = NULL;
|
||||||
|
|
||||||
while (client->advertised_leases != NULL) {
|
while (client->advertised_leases != NULL) {
|
||||||
lease = client->advertised_leases;
|
lease = client->advertised_leases;
|
||||||
client->advertised_leases = lease->next;
|
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.",
|
"Trying other servers.",
|
||||||
nscore, sscore);
|
nscore, sscore);
|
||||||
|
|
||||||
dhc6_lease_destroy(client->selected_lease, MDL);
|
dhc6_lease_destroy(&client->selected_lease, MDL);
|
||||||
client->selected_lease = NULL;
|
client->selected_lease = NULL;
|
||||||
|
|
||||||
start_selecting6(client);
|
start_selecting6(client);
|
||||||
@ -1807,7 +1822,7 @@ init_handler(struct packet *packet, struct client_state *client)
|
|||||||
|
|
||||||
if (dhc6_check_advertise(lease) != ISC_R_SUCCESS) {
|
if (dhc6_check_advertise(lease) != ISC_R_SUCCESS) {
|
||||||
log_debug("PRC: Lease failed to satisfy.");
|
log_debug("PRC: Lease failed to satisfy.");
|
||||||
dhc6_lease_destroy(lease, MDL);
|
dhc6_lease_destroy(&lease, MDL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2030,7 +2045,7 @@ do_select6(void *input)
|
|||||||
lease->server_id.data, 56));
|
lease->server_id.data, 56));
|
||||||
|
|
||||||
/* Get rid of the lease that timed/counted out. */
|
/* Get rid of the lease that timed/counted out. */
|
||||||
dhc6_lease_destroy(lease, MDL);
|
dhc6_lease_destroy(&lease, MDL);
|
||||||
client->selected_lease = NULL;
|
client->selected_lease = NULL;
|
||||||
|
|
||||||
/* If there are more leases great. If not, get more. */
|
/* 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);
|
check_status = dhc6_check_reply(client, lease);
|
||||||
if (check_status != ISC_R_SUCCESS) {
|
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
|
/* If no action was taken, but there is an error, then
|
||||||
* we wait for a retransmission.
|
* we wait for a retransmission.
|
||||||
@ -2320,7 +2335,7 @@ reply_handler(struct packet *packet, struct client_state *client)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (client->selected_lease != NULL) {
|
if (client->selected_lease != NULL) {
|
||||||
dhc6_lease_destroy(client->selected_lease, MDL);
|
dhc6_lease_destroy(&client->selected_lease, MDL);
|
||||||
client->selected_lease = NULL;
|
client->selected_lease = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2329,7 +2344,7 @@ reply_handler(struct packet *packet, struct client_state *client)
|
|||||||
if (client->active_lease == NULL)
|
if (client->active_lease == NULL)
|
||||||
log_fatal("Impossible condition at %s:%d.", MDL);
|
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;
|
client->active_lease = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2341,7 +2356,7 @@ reply_handler(struct packet *packet, struct client_state *client)
|
|||||||
if (client->active_lease == NULL)
|
if (client->active_lease == NULL)
|
||||||
log_fatal("Impossible condition at %s:%d.", MDL);
|
log_fatal("Impossible condition at %s:%d.", MDL);
|
||||||
|
|
||||||
dhc6_lease_destroy(lease, MDL);
|
dhc6_lease_destroy(&lease, MDL);
|
||||||
start_bound(client);
|
start_bound(client);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2353,7 +2368,7 @@ reply_handler(struct packet *packet, struct client_state *client)
|
|||||||
|
|
||||||
/* Cleanup if a previous attempt to go bound failed. */
|
/* Cleanup if a previous attempt to go bound failed. */
|
||||||
if (client->old_lease != NULL) {
|
if (client->old_lease != NULL) {
|
||||||
dhc6_lease_destroy(client->old_lease, MDL);
|
dhc6_lease_destroy(&client->old_lease, MDL);
|
||||||
client->old_lease = NULL;
|
client->old_lease = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2367,7 +2382,7 @@ reply_handler(struct packet *packet, struct client_state *client)
|
|||||||
lease = client->advertised_leases;
|
lease = client->advertised_leases;
|
||||||
client->advertised_leases = lease->next;
|
client->advertised_leases = lease->next;
|
||||||
|
|
||||||
dhc6_lease_destroy(lease, MDL);
|
dhc6_lease_destroy(&lease, MDL);
|
||||||
}
|
}
|
||||||
|
|
||||||
start_bound(client);
|
start_bound(client);
|
||||||
@ -2547,7 +2562,7 @@ dhc6_check_times(struct client_state *client)
|
|||||||
* schedule a future request (using 4-pkt info-request model).
|
* schedule a future request (using 4-pkt info-request model).
|
||||||
*/
|
*/
|
||||||
if (has_addrs == ISC_FALSE) {
|
if (has_addrs == ISC_FALSE) {
|
||||||
dhc6_lease_destroy(client->active_lease, MDL);
|
dhc6_lease_destroy(&client->active_lease, MDL);
|
||||||
client->active_lease = NULL;
|
client->active_lease = NULL;
|
||||||
|
|
||||||
/* Go back to the beginning. */
|
/* Go back to the beginning. */
|
||||||
@ -2822,7 +2837,7 @@ start_bound(struct client_state *client)
|
|||||||
go_daemon();
|
go_daemon();
|
||||||
|
|
||||||
if (client->old_lease != NULL) {
|
if (client->old_lease != NULL) {
|
||||||
dhc6_lease_destroy(client->old_lease, MDL);
|
dhc6_lease_destroy(&client->old_lease, MDL);
|
||||||
client->old_lease = NULL;
|
client->old_lease = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3131,7 +3146,7 @@ do_expire(void *input)
|
|||||||
log_info("PRC: Bound lease is devoid of active addresses."
|
log_info("PRC: Bound lease is devoid of active addresses."
|
||||||
" Re-initializing.");
|
" Re-initializing.");
|
||||||
|
|
||||||
dhc6_lease_destroy(lease, MDL);
|
dhc6_lease_destroy(&lease, MDL);
|
||||||
client->active_lease = NULL;
|
client->active_lease = NULL;
|
||||||
|
|
||||||
start_init6(client);
|
start_init6(client);
|
||||||
|
@ -2463,7 +2463,7 @@ void dhcpv6_client_assignments(void);
|
|||||||
|
|
||||||
/* dhc6.c */
|
/* dhc6.c */
|
||||||
void form_duid(struct data_string *duid, const char *file, int line);
|
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_init6(struct client_state *client);
|
||||||
void start_confirm6(struct client_state *client);
|
void start_confirm6(struct client_state *client);
|
||||||
void start_release6(struct client_state *client);
|
void start_release6(struct client_state *client);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user