11.02.2016 00:21, Josef Bacik пишет:
I noticed when debugging a problem that we'd corrupt memory if our dns server
didn't respond fast enough and we ended up asking for both an AAAA and A record
for a server. The problem is we alloc data->addresses based on the number of
addresses in the packet, but we populate it based on data->naddresses. So we
get the AAAA record with one address, and we add that, then we get the A record
with one address and now data->naddresses == 1 but the ancount is 1, so we
allocate data->addresses to hold one address but write the new address outside
the array. We also leak the old addresses memory. So fix this by noticing if
we already have an address and free the old memory and reset naddresses so we
don't overflow our new array.
Signed-off-by: Josef Bacik <address@hidden>
---
grub-core/net/dns.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
index 86e609b..7a6c4b4 100644
--- a/grub-core/net/dns.c
+++ b/grub-core/net/dns.c
@@ -276,6 +276,9 @@ recv_hook (grub_net_udp_socket_t sock __attribute__
((unused)),
ptr++;
ptr += 4;
}
+ if (*data->naddresses)
+ grub_free (*data->addresses);
+ *data->naddresses = 0;
*data->addresses = grub_malloc (sizeof ((*data->addresses)[0])
* grub_be_to_cpu16 (head->ancount));
Hmm ... cannot we resize it?
*data->addresses = grub_realloc (*data->addresses,
sizeof ((*data->addresses)[0]) * (*data->naddresses += grub_be_to_cpu16
(head->ancount)))
as adjusted to not leak old pointer.
This way answers we got before would not be lost.