grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v1] dns: fixed lookup error when no IPv6 is returned


From: Renaud Métrich
Subject: [PATCH v1] dns: fixed lookup error when no IPv6 is returned
Date: Fri, 28 Apr 2023 13:17:44 +0200

When trying to resolve DNS names into IP addresses, the DNS code fails
from time to time with the following error:
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
error: ../../grub-core/net/dns.c:688:no DNS record found.
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

This happens when both IPv4 and IPv6 queries are performed against the
DNS server (e.g. 8.8.8.8) but there is no IP returned for IPv6 query, as
shown below:
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
grub> net_del_dns 192.168.122.1
grub> net_add_dns 8.8.8.8
grub> net_nslookup ipv4.test-ipv6.com
error: ../../grub-core/net/dns.c:688:no DNS record found.
grub> net_nslookup ipv4.test-ipv6.com
216.218.228.115
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

The root cause is the code exiting prematurely when the data->addresses
buffer has been allocated in recv_hook(), even if there was no address
returned last time recv_hook() executed.

This patch additionally simplifies the error handling.

Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
---
 grub-core/net/dns.c | 69 +++++++++++++++------------------------------
 1 file changed, 23 insertions(+), 46 deletions(-)

diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
index afa389494..2dfb98d98 100644
--- a/grub-core/net/dns.c
+++ b/grub-core/net/dns.c
@@ -261,43 +261,27 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ 
((unused)),
   /* Code apparently assumed that only one packet is received as response.
      We may get multiple responses due to network condition, so check here
      and quit early. */
-  if (*data->addresses)
-    {
-      grub_netbuff_free (nb);
-      return GRUB_ERR_NONE;
-    }
+  if (*data->naddresses)
+    goto out;
 
   head = (struct dns_header *) nb->data;
   ptr = (grub_uint8_t *) (head + 1);
   if (ptr >= nb->tail)
-    {
-      grub_netbuff_free (nb);
-      return GRUB_ERR_NONE;
-    }
+    goto out;
 
   if (head->id != data->id)
-    {
-      grub_netbuff_free (nb);
-      return GRUB_ERR_NONE;
-    }
+    goto out;
   if (!(head->flags & FLAGS_RESPONSE) || (head->flags & FLAGS_OPCODE))
-    {
-      grub_netbuff_free (nb);
-      return GRUB_ERR_NONE;
-    }
+    goto out;
   if (head->ra_z_r_code & ERRCODE_MASK)
     {
       data->dns_err = 1;
-      grub_netbuff_free (nb);
-      return GRUB_ERR_NONE;
+      goto out;
     }
   for (i = 0; i < grub_be_to_cpu16 (head->qdcount); i++)
     {
       if (ptr >= nb->tail)
-       {
-         grub_netbuff_free (nb);
-         return GRUB_ERR_NONE;
-       }
+       goto out;
       while (ptr < nb->tail && !((*ptr & 0xc0) || *ptr == 0))
        ptr += *ptr + 1;
       if (ptr < nb->tail && (*ptr & 0xc0))
@@ -310,8 +294,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ 
((unused)),
   if (!*data->addresses)
     {
       grub_errno = GRUB_ERR_NONE;
-      grub_netbuff_free (nb);
-      return GRUB_ERR_NONE;
+      goto out;
     }
   reparse_ptr = ptr;
  reparse:
@@ -322,11 +305,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ 
((unused)),
       grub_uint32_t ttl = 0;
       grub_uint16_t length;
       if (ptr >= nb->tail)
-       {
-         if (!*data->naddresses)
-           grub_free (*data->addresses);
-         return GRUB_ERR_NONE;
-       }
+       goto out;
       ignored = !check_name (ptr, nb->data, nb->tail, data->name);
       while (ptr < nb->tail && !((*ptr & 0xc0) || *ptr == 0))
        ptr += *ptr + 1;
@@ -334,12 +313,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ 
((unused)),
        ptr++;
       ptr++;
       if (ptr + 10 >= nb->tail)
-       {
-         if (!*data->naddresses)
-           grub_free (*data->addresses);
-         grub_netbuff_free (nb);
-         return GRUB_ERR_NONE;
-       }
+       goto out;
       if (*ptr++ != 0)
        ignored = 1;
       class = *ptr++;
@@ -355,12 +329,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ 
((unused)),
       length = *ptr++ << 8;
       length |= *ptr++;
       if (ptr + length > nb->tail)
-       {
-         if (!*data->naddresses)
-           grub_free (*data->addresses);
-         grub_netbuff_free (nb);
-         return GRUB_ERR_NONE;
-       }
+       goto out;
       if (!ignored)
        {
          if (ttl_all > ttl)
@@ -374,6 +343,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ 
((unused)),
                = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
              grub_memcpy (&(*data->addresses)[*data->naddresses].ipv4,
                           ptr, 4);
+             grub_dprintf ("dns", "got A 0x%x\n", 
(*data->addresses)[*data->naddresses].ipv4);
              (*data->naddresses)++;
              data->stop = 1;
              break;
@@ -384,6 +354,10 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ 
((unused)),
                = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
              grub_memcpy (&(*data->addresses)[*data->naddresses].ipv6,
                           ptr, 16);
+             grub_dprintf ("dns", "got AAAA 0x%lx%lx\n",
+               (*data->addresses)[*data->naddresses].ipv6[0],
+               (*data->addresses)[*data->naddresses].ipv6[1]
+             );
              (*data->naddresses)++;
              data->stop = 1;
              break;
@@ -400,15 +374,14 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ 
((unused)),
              if (!data->name)
                {
                  data->dns_err = 1;
-                 grub_errno = 0;
-                 return GRUB_ERR_NONE;
+                 grub_errno = GRUB_ERR_NONE;
+                 goto out;
                }
              grub_dprintf ("dns", "CNAME %s\n", data->name);
              if (grub_strcmp (redirect_save, data->name) == 0)
                {
                  data->dns_err = 1;
-                 grub_free (redirect_save);
-                 return GRUB_ERR_NONE;
+                 goto out;
                }
              goto reparse;
            }
@@ -440,8 +413,12 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ 
((unused)),
                   *data->naddresses
                   * sizeof (dns_cache[h].addresses[0]));
     }
+
+ out:
   grub_netbuff_free (nb);
   grub_free (redirect_save);
+  if (!*data->naddresses)
+    grub_free (*data->addresses);
   return GRUB_ERR_NONE;
 }
 
-- 
2.40.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]