[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
- [PATCH vRESEND 1/4] Add "noescape" argument to cmdline creation,
Vladimir Serbinenko <=