grub-devel
[Top][All Lists]
Advanced

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

[PATCH v3 03/10] net: dhcp: Allow overloading legacy bootfile and name f


From: Andre Przywara
Subject: [PATCH v3 03/10] net: dhcp: Allow overloading legacy bootfile and name field
Date: Thu, 7 Mar 2019 15:14:09 +0000

From: Andrei Borzenkov <address@hidden>

DHCP specifies a special dummy option OVERLOAD, to allow DHCP options to
spill over into the (legacy) BOOTFILE and SNAME fields.

Parse and handle this option properly.

Signed-off-by: Andre Przywara <address@hidden>
---
 grub-core/net/bootp.c | 59 ++++++++++++++++++++++++++++++++++++++++++-
 include/grub/net.h    |  1 +
 2 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
index 8d6763689..860d9c80d 100644
--- a/grub-core/net/bootp.c
+++ b/grub-core/net/bootp.c
@@ -25,11 +25,19 @@
 #include <grub/net/udp.h>
 #include <grub/datetime.h>
 
+enum
+{
+  GRUB_DHCP_OPT_OVERLOAD_FILE = 1,
+  GRUB_DHCP_OPT_OVERLOAD_SNAME = 2,
+};
+
 static const void *
 find_dhcp_option (const struct grub_net_bootp_packet *bp, grub_size_t size,
                  grub_uint8_t opt_code, grub_uint8_t *opt_len)
 {
   const grub_uint8_t *ptr;
+  grub_uint8_t overload = 0;
+  int end = 0;
   grub_size_t i;
 
   if (opt_len)
@@ -54,6 +62,7 @@ find_dhcp_option (const struct grub_net_bootp_packet *bp, 
grub_size_t size,
   size -= sizeof (*bp);
   i = sizeof (grub_uint32_t);
 
+again:
   while (i < size)
     {
       grub_uint8_t tagtype;
@@ -67,7 +76,10 @@ find_dhcp_option (const struct grub_net_bootp_packet *bp, 
grub_size_t size,
 
       /* End tag.  */
       if (tagtype == GRUB_NET_BOOTP_END)
-       break;
+       {
+         end = 1;
+         break;
+       }
 
       if (i >= size)
        return NULL;
@@ -84,9 +96,54 @@ find_dhcp_option (const struct grub_net_bootp_packet *bp, 
grub_size_t size,
          return &ptr[i];
        }
 
+      if (tagtype == GRUB_NET_DHCP_OVERLOAD && taglength == 1)
+       overload = ptr[i];
+
       i += taglength;
     }
 
+  if (!end)
+    return NULL;
+
+  /* RFC2131, 4.1, 23ff:
+   * If the options in a DHCP message extend into the 'sname' and 'file'
+   * fields, the 'option overload' option MUST appear in the 'options'
+   * field, with value 1, 2 or 3, as specified in RFC 1533.  If the
+   * 'option overload' option is present in the 'options' field, the
+   * options in the 'options' field MUST be terminated by an 'end' option,
+   * and MAY contain one or more 'pad' options to fill the options field.
+   * The options in the 'sname' and 'file' fields (if in use as indicated
+   * by the 'options overload' option) MUST begin with the first octet of
+   * the field, MUST be terminated by an 'end' option, and MUST be
+   * followed by 'pad' options to fill the remainder of the field.  Any
+   * individual option in the 'options', 'sname' and 'file' fields MUST be
+   * entirely contained in that field.  The options in the 'options' field
+   * MUST be interpreted first, so that any 'option overload' options may
+   * be interpreted.  The 'file' field MUST be interpreted next (if the
+   * 'option overload' option indicates that the 'file' field contains
+   * DHCP options), followed by the 'sname' field.
+   *
+   * FIXME: We do not explicitly check for trailing 'pad' options here.
+   */
+  end = 0;
+  if (overload & GRUB_DHCP_OPT_OVERLOAD_FILE)
+  {
+    overload &= ~GRUB_DHCP_OPT_OVERLOAD_FILE;
+    ptr = (grub_uint8_t *) &bp->boot_file[0];
+    size = sizeof (bp->boot_file);
+    i = 0;
+    goto again;
+  }
+
+  if (overload & GRUB_DHCP_OPT_OVERLOAD_SNAME)
+  {
+    overload &= ~GRUB_DHCP_OPT_OVERLOAD_SNAME;
+    ptr = (grub_uint8_t *) &bp->server_name[0];
+    size = sizeof (bp->server_name);
+    i = 0;
+    goto again;
+  }
+
   return NULL;
 }
 
diff --git a/include/grub/net.h b/include/grub/net.h
index 1096b2432..0c7286bd2 100644
--- a/include/grub/net.h
+++ b/include/grub/net.h
@@ -457,6 +457,7 @@ enum
     GRUB_NET_BOOTP_DOMAIN = 0x0f,
     GRUB_NET_BOOTP_ROOT_PATH = 0x11,
     GRUB_NET_BOOTP_EXTENSIONS_PATH = 0x12,
+    GRUB_NET_DHCP_OVERLOAD = 52,
     GRUB_NET_BOOTP_END = 0xff
   };
 
-- 
2.17.1




reply via email to

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