grub-devel
[Top][All Lists]
Advanced

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

[PATCH vRESEND 1/4] Add "noescape" argument to cmdline creation


From: Vladimir Serbinenko
Subject: [PATCH vRESEND 1/4] Add "noescape" argument to cmdline creation
Date: Fri, 17 May 2024 10:52:47 +0300

If OS parses in a way different from sh-like that GRUB does, escaping does
more harm than good. Note that allows to specify entire command line in a
single argument e.g. multiboot --noescape /kernel "a b c".

This is needed to boot Solaris/Illumos on some boot paths that need quotes.

Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
---
 grub-core/lib/cmdline.c                   | 40 ++++++++++++++---------
 grub-core/loader/arm/linux.c              |  4 +--
 grub-core/loader/arm64/xen_boot.c         |  4 +--
 grub-core/loader/efi/linux.c              |  4 +--
 grub-core/loader/i386/linux.c             |  2 +-
 grub-core/loader/i386/multiboot_mbi.c     |  8 ++---
 grub-core/loader/i386/pc/linux.c          |  2 +-
 grub-core/loader/i386/xen.c               |  6 ++--
 grub-core/loader/mips/linux.c             |  4 +--
 grub-core/loader/multiboot_mbi2.c         |  8 ++---
 grub-core/loader/powerpc/ieee1275/linux.c |  4 +--
 grub-core/loader/sparc64/ieee1275/linux.c |  4 +--
 include/grub/lib/cmdline.h                |  5 +--
 13 files changed, 52 insertions(+), 43 deletions(-)

diff --git a/grub-core/lib/cmdline.c b/grub-core/lib/cmdline.c
index ed0b149dc..715392fac 100644
--- a/grub-core/lib/cmdline.c
+++ b/grub-core/lib/cmdline.c
@@ -45,14 +45,14 @@ static unsigned int check_arg (char *c, int *has_space)
   return size;
 }
 
-unsigned int grub_loader_cmdline_size (int argc, char *argv[])
+unsigned int grub_loader_cmdline_size (int argc, char *argv[], int noescape)
 {
   int i;
   unsigned int size = 0;
 
   for (i = 0; i < argc; i++)
     {
-      size += check_arg (argv[i], 0);
+      size += noescape ? grub_strlen(argv[i]) : check_arg (argv[i], 0);
       size++; /* Separator space or NULL.  */
     }
 
@@ -64,16 +64,17 @@ unsigned int grub_loader_cmdline_size (int argc, char 
*argv[])
 
 grub_err_t
 grub_create_loader_cmdline (int argc, char *argv[], char *buf,
-                           grub_size_t size, enum grub_verify_string_type type)
+                           grub_size_t size, enum grub_verify_string_type type,
+                           int noescape)
 {
-  int i, space;
+  int i, space = 0;
   unsigned int arg_size;
   char *c, *orig_buf = buf;
 
   for (i = 0; i < argc; i++)
     {
       c = argv[i];
-      arg_size = check_arg(argv[i], &space);
+      arg_size = noescape ? grub_strlen(argv[i]) : check_arg(argv[i], &space);
       arg_size++; /* Separator space or NULL.  */
 
       if (size < arg_size)
@@ -81,21 +82,28 @@ grub_create_loader_cmdline (int argc, char *argv[], char 
*buf,
 
       size -= arg_size;
 
-      if (space)
-       *buf++ = '"';
-
-      while (*c)
+      if (noescape)
        {
-         if (*c == '\\' || *c == '\'' || *c == '"')
-           *buf++ = '\\';
-
-         *buf++ = *c;
-         c++;
+         grub_memcpy(buf, c, arg_size);
+         buf += arg_size - 1;
        }
+      else
+       {
+         if (space)
+           *buf++ = '"';
 
-      if (space)
-       *buf++ = '"';
+         while (*c)
+           {
+             if (*c == '\\' || *c == '\'' || *c == '"')
+               *buf++ = '\\';
 
+             *buf++ = *c;
+             c++;
+           }
+
+         if (space)
+           *buf++ = '"';
+       }
       *buf++ = ' ';
     }
 
diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c
index 19ddedbc2..6a052a0da 100644
--- a/grub-core/loader/arm/linux.c
+++ b/grub-core/loader/arm/linux.c
@@ -375,7 +375,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 
   grub_loader_set (linux_boot, linux_unload, 0);
 
-  size = grub_loader_cmdline_size (argc, argv);
+  size = grub_loader_cmdline_size (argc, argv, 0);
   linux_args = grub_malloc (size + sizeof (LINUX_IMAGE));
   if (!linux_args)
     {
@@ -387,7 +387,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
   err = grub_create_loader_cmdline (argc, argv,
                                    linux_args + sizeof (LINUX_IMAGE) - 1, size,
-                                   GRUB_VERIFY_KERNEL_CMDLINE);
+                                   GRUB_VERIFY_KERNEL_CMDLINE, 0);
   if (err)
     goto fail;
 
diff --git a/grub-core/loader/arm64/xen_boot.c 
b/grub-core/loader/arm64/xen_boot.c
index 26e1472c9..7b55742f5 100644
--- a/grub-core/loader/arm64/xen_boot.c
+++ b/grub-core/loader/arm64/xen_boot.c
@@ -345,7 +345,7 @@ xen_boot_binary_load (struct xen_boot_binary *binary, 
grub_file_t file,
 
   if (argc > 1)
     {
-      binary->cmdline_size = grub_loader_cmdline_size (argc - 1, argv + 1);
+      binary->cmdline_size = grub_loader_cmdline_size (argc - 1, argv + 1, 0);
       binary->cmdline = grub_zalloc (binary->cmdline_size);
       if (!binary->cmdline)
        {
@@ -355,7 +355,7 @@ xen_boot_binary_load (struct xen_boot_binary *binary, 
grub_file_t file,
        }
       grub_create_loader_cmdline (argc - 1, argv + 1, binary->cmdline,
                                  binary->cmdline_size,
-                                 GRUB_VERIFY_KERNEL_CMDLINE);
+                                 GRUB_VERIFY_KERNEL_CMDLINE, 0);
       grub_dprintf ("xen_loader",
                    "Xen_boot cmdline @ %p %s, size: %d\n",
                    binary->cmdline, binary->cmdline, binary->cmdline_size);
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index bfbd95aee..dc94a9572 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -533,7 +533,7 @@ fallback:
 
   grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
 
-  cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
+  cmdline_size = grub_loader_cmdline_size (argc, argv, 0) + sizeof 
(LINUX_IMAGE);
   linux_args = grub_malloc (cmdline_size);
   if (!linux_args)
     {
@@ -544,7 +544,7 @@ fallback:
   err = grub_create_loader_cmdline (argc, argv,
                                    linux_args + sizeof (LINUX_IMAGE) - 1,
                                    cmdline_size,
-                                   GRUB_VERIFY_KERNEL_CMDLINE);
+                                   GRUB_VERIFY_KERNEL_CMDLINE, 0);
   if (err)
     goto fail;
 
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index 977757f2c..66a9a7136 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -1013,7 +1013,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ 
((unused)),
                                      + sizeof (LINUX_IMAGE) - 1,
                                      maximal_cmdline_size
                                      - (sizeof (LINUX_IMAGE) - 1),
-                                     GRUB_VERIFY_KERNEL_CMDLINE);
+                                     GRUB_VERIFY_KERNEL_CMDLINE, 0);
     if (err)
       goto fail;
   }
diff --git a/grub-core/loader/i386/multiboot_mbi.c 
b/grub-core/loader/i386/multiboot_mbi.c
index bdaf67ad0..326827089 100644
--- a/grub-core/loader/i386/multiboot_mbi.c
+++ b/grub-core/loader/i386/multiboot_mbi.c
@@ -668,7 +668,7 @@ grub_multiboot_init_mbi (int argc, char *argv[])
 
   grub_multiboot_free_mbi ();
 
-  len = grub_loader_cmdline_size (argc, argv);
+  len = grub_loader_cmdline_size (argc, argv, 0);
 
   cmdline = grub_malloc (len);
   if (! cmdline)
@@ -676,7 +676,7 @@ grub_multiboot_init_mbi (int argc, char *argv[])
   cmdline_size = len;
 
   return grub_create_loader_cmdline (argc, argv, cmdline,
-                                    cmdline_size, GRUB_VERIFY_KERNEL_CMDLINE);
+                                    cmdline_size, GRUB_VERIFY_KERNEL_CMDLINE, 
0);
 }
 
 grub_err_t
@@ -694,7 +694,7 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t 
size,
   newmod->size = size;
   newmod->next = 0;
 
-  len = grub_loader_cmdline_size (argc, argv);
+  len = grub_loader_cmdline_size (argc, argv, 0);
 
   newmod->cmdline = grub_malloc (len);
   if (! newmod->cmdline)
@@ -706,7 +706,7 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t 
size,
   total_modcmd += ALIGN_UP (len, 4);
 
   err = grub_create_loader_cmdline (argc, argv, newmod->cmdline,
-                                   newmod->cmdline_size, 
GRUB_VERIFY_MODULE_CMDLINE);
+                                   newmod->cmdline_size, 
GRUB_VERIFY_MODULE_CMDLINE, 0);
   if (err)
     {
       grub_free (newmod);
diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
index 4adeee9ae..e2209cdbe 100644
--- a/grub-core/loader/i386/pc/linux.c
+++ b/grub-core/loader/i386/pc/linux.c
@@ -345,7 +345,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
                                    + GRUB_LINUX_CL_OFFSET + sizeof 
(LINUX_IMAGE) - 1,
                                    maximal_cmdline_size
                                    - (sizeof (LINUX_IMAGE) - 1),
-                                   GRUB_VERIFY_KERNEL_CMDLINE);
+                                   GRUB_VERIFY_KERNEL_CMDLINE, 0);
   if (err)
     goto fail;
 
diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c
index 3b856e842..d24ef151b 100644
--- a/grub-core/loader/i386/xen.c
+++ b/grub-core/loader/i386/xen.c
@@ -650,7 +650,7 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)),
   err = grub_create_loader_cmdline (argc - 1, argv + 1,
                                    (char *) xen_state.next_start.cmd_line,
                                    sizeof (xen_state.next_start.cmd_line) - 1,
-                                   GRUB_VERIFY_KERNEL_CMDLINE);
+                                   GRUB_VERIFY_KERNEL_CMDLINE, 0);
   if (err)
     return err;
 
@@ -910,7 +910,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ 
((unused)),
     return grub_errno;
   size = grub_file_size (file);
 
-  cmdline_len = grub_loader_cmdline_size (argc - 1, argv + 1);
+  cmdline_len = grub_loader_cmdline_size (argc - 1, argv + 1, 0);
 
   err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch,
                                         xen_state.max_addr, cmdline_len);
@@ -919,7 +919,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ 
((unused)),
 
   err = grub_create_loader_cmdline (argc - 1, argv + 1,
                                    get_virtual_current_address (ch), 
cmdline_len,
-                                   GRUB_VERIFY_MODULE_CMDLINE);
+                                   GRUB_VERIFY_MODULE_CMDLINE, 0);
   if (err)
     goto fail;
 
diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c
index 7264ba2b6..dedf61280 100644
--- a/grub-core/loader/mips/linux.c
+++ b/grub-core/loader/mips/linux.c
@@ -304,7 +304,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 
 #ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
   /* Create kernel command line.  */
-  size = grub_loader_cmdline_size(argc, argv);
+  size = grub_loader_cmdline_size(argc, argv, 0);
   params = grub_malloc (size + sizeof (LINUX_IMAGE));
   if (! params)
     {
@@ -314,7 +314,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 
   grub_memcpy (params, LINUX_IMAGE, sizeof (LINUX_IMAGE));
   grub_create_loader_cmdline (argc, argv, params + sizeof (LINUX_IMAGE) - 1,
-                             size, GRUB_VERIFY_KERNEL_CMDLINE);
+                             size, GRUB_VERIFY_KERNEL_CMDLINE, 0);
 #else
   linux_argv = extra;
   argv_off = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground;
diff --git a/grub-core/loader/multiboot_mbi2.c 
b/grub-core/loader/multiboot_mbi2.c
index 00a48413c..8a81a0359 100644
--- a/grub-core/loader/multiboot_mbi2.c
+++ b/grub-core/loader/multiboot_mbi2.c
@@ -1037,7 +1037,7 @@ grub_multiboot2_init_mbi (int argc, char *argv[])
 
   grub_multiboot2_free_mbi ();
 
-  len = grub_loader_cmdline_size (argc, argv);
+  len = grub_loader_cmdline_size (argc, argv, 0);
 
   cmdline = grub_malloc (len);
   if (! cmdline)
@@ -1045,7 +1045,7 @@ grub_multiboot2_init_mbi (int argc, char *argv[])
   cmdline_size = len;
 
   return grub_create_loader_cmdline (argc, argv, cmdline, cmdline_size,
-                                    GRUB_VERIFY_KERNEL_CMDLINE);
+                                    GRUB_VERIFY_KERNEL_CMDLINE, 0);
 }
 
 grub_err_t
@@ -1062,7 +1062,7 @@ grub_multiboot2_add_module (grub_addr_t start, 
grub_size_t size,
   newmod->start = start;
   newmod->size = size;
 
-  len = grub_loader_cmdline_size (argc, argv);
+  len = grub_loader_cmdline_size (argc, argv, 0);
 
   newmod->cmdline = grub_malloc (len);
   if (! newmod->cmdline)
@@ -1074,7 +1074,7 @@ grub_multiboot2_add_module (grub_addr_t start, 
grub_size_t size,
   total_modcmd += ALIGN_UP (len, MULTIBOOT_TAG_ALIGN);
 
   err = grub_create_loader_cmdline (argc, argv, newmod->cmdline,
-                                   newmod->cmdline_size, 
GRUB_VERIFY_MODULE_CMDLINE);
+                                   newmod->cmdline_size, 
GRUB_VERIFY_MODULE_CMDLINE, 0);
   if (err)
     {
       grub_free (newmod->cmdline);
diff --git a/grub-core/loader/powerpc/ieee1275/linux.c 
b/grub-core/loader/powerpc/ieee1275/linux.c
index 4864e5fb0..45461f26a 100644
--- a/grub-core/loader/powerpc/ieee1275/linux.c
+++ b/grub-core/loader/powerpc/ieee1275/linux.c
@@ -306,7 +306,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
       goto out;
     }
 
-  size = grub_loader_cmdline_size(argc, argv);
+  size = grub_loader_cmdline_size(argc, argv, 0);
   linux_args = grub_malloc (size + sizeof (LINUX_IMAGE));
   if (! linux_args)
     goto out;
@@ -314,7 +314,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   /* Create kernel command line.  */
   grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
   if (grub_create_loader_cmdline (argc, argv, linux_args + sizeof 
(LINUX_IMAGE) - 1,
-                                 size, GRUB_VERIFY_KERNEL_CMDLINE))
+                                 size, GRUB_VERIFY_KERNEL_CMDLINE, 0))
     goto out;
 
 out:
diff --git a/grub-core/loader/sparc64/ieee1275/linux.c 
b/grub-core/loader/sparc64/ieee1275/linux.c
index ac2206f3c..de31a0792 100644
--- a/grub-core/loader/sparc64/ieee1275/linux.c
+++ b/grub-core/loader/sparc64/ieee1275/linux.c
@@ -332,7 +332,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
       goto out;
     }
 
-  size = grub_loader_cmdline_size(argc, argv);
+  size = grub_loader_cmdline_size(argc, argv, 0);
 
   linux_args = grub_malloc (size + sizeof (LINUX_IMAGE));
   if (! linux_args)
@@ -341,7 +341,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   /* Create kernel command line.  */
   grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
   if (grub_create_loader_cmdline (argc, argv, linux_args + sizeof 
(LINUX_IMAGE) - 1,
-                                 size, GRUB_VERIFY_KERNEL_CMDLINE))
+                                 size, GRUB_VERIFY_KERNEL_CMDLINE, 0))
     goto out;
 
 out:
diff --git a/include/grub/lib/cmdline.h b/include/grub/lib/cmdline.h
index cdca09b7a..c1210ec21 100644
--- a/include/grub/lib/cmdline.h
+++ b/include/grub/lib/cmdline.h
@@ -25,8 +25,9 @@
 
 #define LINUX_IMAGE "BOOT_IMAGE="
 
-unsigned int grub_loader_cmdline_size (int argc, char *argv[]);
+unsigned int grub_loader_cmdline_size (int argc, char *argv[], int noescape);
 grub_err_t grub_create_loader_cmdline (int argc, char *argv[], char *buf,
-                                      grub_size_t size, enum 
grub_verify_string_type type);
+                                      grub_size_t size, enum 
grub_verify_string_type type,
+                                      int noescape);
 
 #endif /* ! GRUB_CMDLINE_HEADER */
-- 
2.39.2




reply via email to

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