From: Vladimir Serbinenko <phcoder@gmail.com>
To: grub-devel@gnu.org
Cc: Vladimir Serbinenko <phcoder@gmail.com>
Subject: [PATCH vRESEND 1/4] Add "noescape" argument to cmdline creation
Date: Fri, 17 May 2024 10:52:47 +0300 [thread overview]
Message-ID: <20240517075250.2760-1-phcoder@gmail.com> (raw)
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
next reply other threads:[~2024-05-17 7:53 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-17 7:52 Vladimir Serbinenko [this message]
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
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=20240517075250.2760-1-phcoder@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 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.