aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Axtens <dja@axtens.net>2021-09-16 01:29:54 +1000
committerDaniel Kiper <daniel.kiper@oracle.com>2022-06-07 16:39:33 +0200
commitc1b7eef9fa4aaefbf7d0507505c3bb2914e1ad6b (patch)
treeac9ca0a9bc3797716c068f209a421c4af4fe28e7
parentf407e34f3871a4c402bbd516e7c28ea193cef1b7 (diff)
downloadgrub-c1b7eef9fa4aaefbf7d0507505c3bb2914e1ad6b.tar.gz
net/dns: Fix double-free addresses on corrupt DNS response
grub_net_dns_lookup() takes as inputs a pointer to an array of addresses ("addresses") for the given name, and pointer to a number of addresses ("naddresses"). grub_net_dns_lookup() is responsible for allocating "addresses", and the caller is responsible for freeing it if "naddresses" > 0. The DNS recv_hook will sometimes set and free the addresses array, for example if the packet is too short: if (ptr + 10 >= nb->tail) { if (!*data->naddresses) grub_free (*data->addresses); grub_netbuff_free (nb); return GRUB_ERR_NONE; } Later on the nslookup command code unconditionally frees the "addresses" array. Normally this is fine: the array is either populated with valid data or is NULL. But in these sorts of error cases it is neither NULL nor valid and we get a double-free. Only free "addresses" if "naddresses" > 0. It looks like the other use of grub_net_dns_lookup() is not affected. Signed-off-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-rw-r--r--grub-core/net/dns.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
index 27c5f4142..841ede51e 100644
--- a/grub-core/net/dns.c
+++ b/grub-core/net/dns.c
@@ -667,9 +667,11 @@ grub_cmd_nslookup (struct grub_command *cmd __attribute__ ((unused)),
grub_net_addr_to_str (&addresses[i], buf);
grub_printf ("%s\n", buf);
}
- grub_free (addresses);
if (naddresses)
- return GRUB_ERR_NONE;
+ {
+ grub_free (addresses);
+ return GRUB_ERR_NONE;
+ }
return grub_error (GRUB_ERR_NET_NO_DOMAIN, N_("no DNS record found"));
}