From: "Vladimir 'phcoder' Serbinenko" <phcoder@gmail.com>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: [PATCH 1/4] Add "noescape" argument to cmdline creation
Date: Sun, 8 Oct 2023 16:11:38 +0200 [thread overview]
Message-ID: <CAEaD8JO1xdx1g4HnPgjT-tAT5Mg0+gc9iAPYtmsLWnoCD3USGw@mail.gmail.com> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 1 bytes --]
[-- Attachment #1.2: Type: text/html, Size: 23 bytes --]
[-- Attachment #2: 0001-Add-noescape-argument-to-cmdline-creation.patch --]
[-- Type: text/x-diff, Size: 14306 bytes --]
From cadef71f275af55740e33a6f6f7f86b5bd004855 Mon Sep 17 00:00:00 2001
From: Vladimir Serbinenko <phcoder@gmail.com>
Date: Wed, 19 Jul 2023 15:09:47 +0200
Subject: [PATCH 1/4] Add "noescape" argument to cmdline creation
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 11a6e224f..9a98e9bfe 100644
--- a/grub-core/loader/i386/multiboot_mbi.c
+++ b/grub-core/loader/i386/multiboot_mbi.c
@@ -665,7 +665,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)
@@ -673,7 +673,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
@@ -691,7 +691,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)
@@ -703,7 +703,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 e6d071508..a6044b970 100644
--- a/grub-core/loader/powerpc/ieee1275/linux.c
+++ b/grub-core/loader/powerpc/ieee1275/linux.c
@@ -281,7 +281,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;
@@ -289,7 +289,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.42.0
[-- Attachment #3: Type: text/plain, Size: 141 bytes --]
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
reply other threads:[~2023-10-08 14:12 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAEaD8JO1xdx1g4HnPgjT-tAT5Mg0+gc9iAPYtmsLWnoCD3USGw@mail.gmail.com \
--to=phcoder@gmail.com \
--cc=grub-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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 read-only IMAP folder(s) and NNTP newsgroup(s).