diff options
author | Daniel Axtens <dja@axtens.net> | 2021-09-16 01:29:54 +1000 |
---|---|---|
committer | Daniel Kiper <daniel.kiper@oracle.com> | 2022-06-07 16:39:33 +0200 |
commit | c1b7eef9fa4aaefbf7d0507505c3bb2914e1ad6b (patch) | |
tree | ac9ca0a9bc3797716c068f209a421c4af4fe28e7 | |
parent | f407e34f3871a4c402bbd516e7c28ea193cef1b7 (diff) | |
download | grub-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.c | 6 |
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")); } |