mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Handle error return from blockdata_alloc in all cases.
This commit is contained in:
@@ -352,8 +352,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
forward->stash = saved_question;
|
forward->stash = saved_question;
|
||||||
saved_question = NULL; /* don't free */
|
saved_question = NULL; /* don't free */
|
||||||
}
|
}
|
||||||
else
|
else if (!(forward->stash = blockdata_alloc((char *)header, plen)))
|
||||||
forward->stash = blockdata_alloc((char *)header, plen);
|
goto reply; /* no mem. return REFUSED */
|
||||||
|
|
||||||
forward->stash_len = plen;
|
forward->stash_len = plen;
|
||||||
forward->frec_src.log_id = daemon->log_id;
|
forward->frec_src.log_id = daemon->log_id;
|
||||||
@@ -995,7 +995,6 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
|
|||||||
answer aside, whilst we get that. */
|
answer aside, whilst we get that. */
|
||||||
if (STAT_ISEQUAL(status, STAT_NEED_DS) || STAT_ISEQUAL(status, STAT_NEED_KEY))
|
if (STAT_ISEQUAL(status, STAT_NEED_DS) || STAT_ISEQUAL(status, STAT_NEED_KEY))
|
||||||
{
|
{
|
||||||
struct frec *new = NULL;
|
|
||||||
struct blockdata *stash;
|
struct blockdata *stash;
|
||||||
|
|
||||||
/* Now save reply pending receipt of key data */
|
/* Now save reply pending receipt of key data */
|
||||||
@@ -1003,8 +1002,9 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
|
|||||||
{
|
{
|
||||||
/* validate routines leave name of required record in daemon->keyname */
|
/* validate routines leave name of required record in daemon->keyname */
|
||||||
unsigned int flags = STAT_ISEQUAL(status, STAT_NEED_KEY) ? FREC_DNSKEY_QUERY : FREC_DS_QUERY;
|
unsigned int flags = STAT_ISEQUAL(status, STAT_NEED_KEY) ? FREC_DNSKEY_QUERY : FREC_DS_QUERY;
|
||||||
|
struct frec *old;
|
||||||
|
|
||||||
if ((new = lookup_frec(daemon->keyname, forward->class, -1, -1, flags, flags)))
|
if ((old = lookup_frec(daemon->keyname, forward->class, -1, -1, flags, flags)))
|
||||||
{
|
{
|
||||||
/* This is tricky; it detects loops in the dependency
|
/* This is tricky; it detects loops in the dependency
|
||||||
graph for DNSSEC validation, say validating A requires DS B
|
graph for DNSSEC validation, say validating A requires DS B
|
||||||
@@ -1015,18 +1015,18 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
|
|||||||
can form a cycle, and under certain circumstances that can lock us in
|
can form a cycle, and under certain circumstances that can lock us in
|
||||||
an infinite loop. Here we transform the situation into ABANDONED. */
|
an infinite loop. Here we transform the situation into ABANDONED. */
|
||||||
struct frec *f;
|
struct frec *f;
|
||||||
for (f = new; f; f = f->blocking_query)
|
for (f = old; f; f = f->blocking_query)
|
||||||
if (f == forward)
|
if (f == forward)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!f)
|
if (!f)
|
||||||
{
|
{
|
||||||
forward->next_dependent = new->dependent;
|
forward->next_dependent = old->dependent;
|
||||||
new->dependent = forward;
|
old->dependent = forward;
|
||||||
/* Make consistent, only replace query copy with unvalidated answer
|
/* Make consistent, only replace query copy with unvalidated answer
|
||||||
when we set ->blocking_query. */
|
when we set ->blocking_query. */
|
||||||
blockdata_free(forward->stash);
|
blockdata_free(forward->stash);
|
||||||
forward->blocking_query = new;
|
forward->blocking_query = old;
|
||||||
forward->stash_len = plen;
|
forward->stash_len = plen;
|
||||||
forward->stash = stash;
|
forward->stash = stash;
|
||||||
return;
|
return;
|
||||||
@@ -1043,6 +1043,8 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
|
|||||||
size_t nn;
|
size_t nn;
|
||||||
int serverind, fd;
|
int serverind, fd;
|
||||||
struct randfd_list *rfds = NULL;
|
struct randfd_list *rfds = NULL;
|
||||||
|
struct frec *new = NULL;
|
||||||
|
struct blockdata *newstash = NULL;
|
||||||
|
|
||||||
/* Make sure we don't expire and free the orig frec during the
|
/* Make sure we don't expire and free the orig frec during the
|
||||||
allocation of a new one: third arg of get_new_frec() does that. */
|
allocation of a new one: third arg of get_new_frec() does that. */
|
||||||
@@ -1052,6 +1054,7 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
|
|||||||
daemon->keyname, forward->class,
|
daemon->keyname, forward->class,
|
||||||
STAT_ISEQUAL(status, STAT_NEED_KEY) ? T_DNSKEY : T_DS, server->edns_pktsz)) &&
|
STAT_ISEQUAL(status, STAT_NEED_KEY) ? T_DNSKEY : T_DS, server->edns_pktsz)) &&
|
||||||
(fd = allocate_rfd(&rfds, server)) != -1 &&
|
(fd = allocate_rfd(&rfds, server)) != -1 &&
|
||||||
|
(newstash = blockdata_alloc((char *)header, nn)) &&
|
||||||
(new = get_new_frec(now, server, 1)))
|
(new = get_new_frec(now, server, 1)))
|
||||||
{
|
{
|
||||||
struct frec *next = new->next;
|
struct frec *next = new->next;
|
||||||
@@ -1081,7 +1084,7 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
|
|||||||
new->new_id = get_id();
|
new->new_id = get_id();
|
||||||
header->id = htons(new->new_id);
|
header->id = htons(new->new_id);
|
||||||
/* Save query for retransmission and de-dup */
|
/* Save query for retransmission and de-dup */
|
||||||
new->stash = blockdata_alloc((char *)header, nn);
|
new->stash = newstash;
|
||||||
new->stash_len = nn;
|
new->stash_len = nn;
|
||||||
if (daemon->fast_retry_time != 0)
|
if (daemon->fast_retry_time != 0)
|
||||||
new->forward_timestamp = dnsmasq_milliseconds();
|
new->forward_timestamp = dnsmasq_milliseconds();
|
||||||
@@ -1104,7 +1107,9 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_rfds(&rfds); /* error unwind */
|
/* error unwind */
|
||||||
|
free_rfds(&rfds);
|
||||||
|
blockdata_free(newstash);
|
||||||
}
|
}
|
||||||
|
|
||||||
blockdata_free(stash); /* don't leak this on failure. */
|
blockdata_free(stash); /* don't leak this on failure. */
|
||||||
|
|||||||
Reference in New Issue
Block a user