The functions grub_create_loader_cmdline and its sibling grub_loader_cmdline_size add extra, unexpected characters to the kernel cmdline. Both functions are supposed to copy each argv[] element verbatim. It is up to the caller of the kernel command ('linux' for example) to add desired quoting or escaping characters for the consumers of the kernel command line. The built-in grub shell gives enough opportunities to construct such argv[] elements.
After this change, these arguments result in the following kernel cmdline: var='val' var="val" var=\'v1 v2\' var=\"v1 v2\" var=\\\"v1 v2\\\" x var=val var=val var='v1 v2' var="v1 v2" var=\"v1 v2\" x Fixes commit 25953e10553dad2e378541a68686fc094603ec54 Signed-off-by: Olaf Hering <o...@aepfle.de> --- grub-core/lib/cmdline.c | 58 ++++++++----------------------------------------- 1 file changed, 9 insertions(+), 49 deletions(-) diff --git a/grub-core/lib/cmdline.c b/grub-core/lib/cmdline.c index ed0b149dc..b572a367f 100644 --- a/grub-core/lib/cmdline.c +++ b/grub-core/lib/cmdline.c @@ -20,31 +20,6 @@ #include <grub/lib/cmdline.h> #include <grub/misc.h> -static unsigned int check_arg (char *c, int *has_space) -{ - int space = 0; - unsigned int size = 0; - - while (*c) - { - if (*c == '\\' || *c == '\'' || *c == '"') - size++; - else if (*c == ' ') - space = 1; - - size++; - c++; - } - - if (space) - size += 2; - - if (has_space) - *has_space = space; - - return size; -} - unsigned int grub_loader_cmdline_size (int argc, char *argv[]) { int i; @@ -52,7 +27,7 @@ unsigned int grub_loader_cmdline_size (int argc, char *argv[]) for (i = 0; i < argc; i++) { - size += check_arg (argv[i], 0); + size += grub_strlen(argv[i]); size++; /* Separator space or NULL. */ } @@ -66,36 +41,21 @@ grub_err_t grub_create_loader_cmdline (int argc, char *argv[], char *buf, grub_size_t size, enum grub_verify_string_type type) { - int i, space; + int i; unsigned int arg_size; - char *c, *orig_buf = buf; + char *orig_buf = buf; for (i = 0; i < argc; i++) { - c = argv[i]; - arg_size = check_arg(argv[i], &space); - arg_size++; /* Separator space or NULL. */ + arg_size = grub_strlen(argv[i]); - if (size < arg_size) + /* Separator space or NULL. */ + if (size < arg_size + 1) break; - size -= arg_size; - - if (space) - *buf++ = '"'; - - while (*c) - { - if (*c == '\\' || *c == '\'' || *c == '"') - *buf++ = '\\'; - - *buf++ = *c; - c++; - } - - if (space) - *buf++ = '"'; - + grub_memcpy(buf, argv[i], arg_size); + size -= arg_size + 1; + buf += arg_size; *buf++ = ' '; } _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel