All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH vRESEND 1/4] Add "noescape" argument to cmdline creation
@ 2024-05-17  7:52 Vladimir Serbinenko
  2024-05-17  7:52 ` [PATCH vRESEND 2/4] loader/multiboot: Add --noescape option Vladimir Serbinenko
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Vladimir Serbinenko @ 2024-05-17  7:52 UTC (permalink / raw)
  To: grub-devel; +Cc: Vladimir Serbinenko

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


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

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

end of thread, other threads:[~2024-05-17  7:53 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-17  7:52 [PATCH vRESEND 1/4] Add "noescape" argument to cmdline creation Vladimir Serbinenko
2024-05-17  7:52 ` [PATCH vRESEND 2/4] loader/multiboot: Add --noescape option Vladimir Serbinenko
2024-05-17  7:52 ` [PATCH vRESEND 3/4] loader/xen: " Vladimir Serbinenko
2024-05-17  7:52 ` [PATCH vRESEND 4/4] 10_illumos: Use --noescape so that $ZFS_BOOTFS is passed properly Vladimir Serbinenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.