xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv3] xen: Add EFI_LOAD_OPTION support
@ 2018-01-23  0:21 Tamas K Lengyel
  2018-01-26 12:46 ` Jan Beulich
  0 siblings, 1 reply; 14+ messages in thread
From: Tamas K Lengyel @ 2018-01-23  0:21 UTC (permalink / raw)
  To: xen-devel; +Cc: openxt, Tamas K Lengyel, Jan Beulich, Tamas K Lengyel

When booting Xen via UEFI the Xen config file can contain multiple sections
each describing different boot options. It is currently only possible to choose
which section to boot with if the buffer contains a string. UEFI provides a
different standard to pass optional arguments to an application, and in this
patch we make Xen properly parse this buffer, thus making it possible to have
separate EFI boot options present for the different config sections.

Signed-off-by: Tamas K Lengyel <lengyelt@ainfosec.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: openxt@googlegroups.com

v3: simplify sanity checking logic
v2: move EFI_LOAD_OPTION definition into file that uses it
    add more sanity checks to validate the buffer
---
 xen/common/efi/boot.c | 49 +++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 43 insertions(+), 6 deletions(-)

diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 469bf980cc..3537fe9588 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -88,6 +88,16 @@ typedef struct _EFI_APPLE_PROPERTIES {
     EFI_APPLE_PROPERTIES_GETALL GetAll;
 } EFI_APPLE_PROPERTIES;
 
+typedef struct _EFI_LOAD_OPTION {
+    UINT32 Attributes;
+    UINT16 FilePathListLength;
+    CHAR16 Description[];
+} EFI_LOAD_OPTION;
+
+#define LOAD_OPTION_ACTIVE              0x00000001
+#define LOAD_OPTION_FORCE_RECONNECT     0x00000002
+#define LOAD_OPTION_HIDDEN              0x00000008
+
 union string {
     CHAR16 *w;
     char *s;
@@ -375,12 +385,39 @@ static void __init PrintErrMesg(const CHAR16 *mesg, EFI_STATUS ErrCode)
 
 static unsigned int __init get_argv(unsigned int argc, CHAR16 **argv,
                                     CHAR16 *cmdline, UINTN cmdsize,
-                                    CHAR16 **options)
+                                    CHAR16 **options, bool *elo_active)
 {
     CHAR16 *ptr = (CHAR16 *)(argv + argc + 1), *prev = NULL;
     bool prev_sep = true;
 
-    for ( ; cmdsize > sizeof(*cmdline) && *cmdline;
+    if ( cmdsize > sizeof(EFI_LOAD_OPTION) &&
+         *(CHAR16 *)((void *)cmdline + cmdsize - sizeof(*cmdline)) != L'\0' )
+    {
+        const EFI_LOAD_OPTION *elo = (const EFI_LOAD_OPTION *)cmdline;
+
+        /* The absolute minimum the size of the buffer it needs to be */
+        size_t size_check = offsetof(EFI_LOAD_OPTION, Description[1]) +
+                            elo->FilePathListLength;
+
+        if ( (elo->Attributes & LOAD_OPTION_ACTIVE) && size_check < cmdsize )
+        {
+            const CHAR16 *desc = elo->Description;
+            size_t desc_length = 0;
+
+            /* Find Description string length in its possible space */
+            while ( desc_length < cmdsize - size_check && *desc++ != L'\0')
+                desc_length += sizeof(*desc);
+
+            if ( size_check + desc_length < cmdsize )
+            {
+                *elo_active = true;
+                cmdline = (void *)cmdline + size_check + desc_length;
+                cmdsize = cmdsize - size_check - desc_length;
+            }
+        }
+    }
+
+    for ( ; cmdsize >= sizeof(*cmdline) && *cmdline;
             cmdsize -= sizeof(*cmdline), ++cmdline )
     {
         bool cur_sep = *cmdline == L' ' || *cmdline == L'\t';
@@ -1071,7 +1108,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     EFI_SHIM_LOCK_PROTOCOL *shim_lock;
     EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL;
     union string section = { NULL }, name;
-    bool base_video = false;
+    bool base_video = false, elo_active = false;
     char *option_str;
     bool use_cfg_file;
 
@@ -1096,17 +1133,17 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     if ( use_cfg_file )
     {
         argc = get_argv(0, NULL, loaded_image->LoadOptions,
-                        loaded_image->LoadOptionsSize, NULL);
+                        loaded_image->LoadOptionsSize, NULL, &elo_active);
         if ( argc > 0 &&
              efi_bs->AllocatePool(EfiLoaderData,
                                   (argc + 1) * sizeof(*argv) +
                                       loaded_image->LoadOptionsSize,
                                   (void **)&argv) == EFI_SUCCESS )
             get_argv(argc, argv, loaded_image->LoadOptions,
-                     loaded_image->LoadOptionsSize, &options);
+                     loaded_image->LoadOptionsSize, &options, &elo_active);
         else
             argc = 0;
-        for ( i = 1; i < argc; ++i )
+        for ( i = !elo_active; i < argc; ++i )
         {
             CHAR16 *ptr = argv[i];
 
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2018-05-22 19:32 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-01-23  0:21 [PATCHv3] xen: Add EFI_LOAD_OPTION support Tamas K Lengyel
2018-01-26 12:46 ` Jan Beulich
2018-01-26 17:35   ` Tamas K Lengyel
2018-01-29  9:18     ` Jan Beulich
2018-02-07 16:00       ` Tamas K Lengyel
2018-03-12 15:00         ` Tamas K Lengyel
2018-03-13  7:47           ` Jan Beulich
2018-03-13 20:58             ` Tamas K Lengyel
2018-05-17  8:03         ` Jan Beulich
2018-05-17 17:42           ` Tamas K Lengyel
2018-05-21 16:59             ` Tamas K Lengyel
2018-05-22  9:42               ` Jan Beulich
2018-05-22 12:24               ` Jan Beulich
2018-05-22 19:31                 ` Tamas K Lengyel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).