grub-lakitu: UPSTREAM: VERIFIERS: Add possibility to verify kernel command lines.
(cherry picked from commit ba5401b19782fb25aa47e388452c39936672a796)
(from phcoder/verifiers branch of git://git.savannah.gnu.org/grub.git)
BUG=b:69569602
TEST=TBD
Change-Id: I52ea7cc053d9ac4d1b6af09517888e3bdab27de0
Reviewed-on: https://chromium-review.googlesource.com/945880
Reviewed-by: Edward Jee <edjee@google.com>
Commit-Queue: Edward Jee <edjee@google.com>
Tested-by: Edward Jee <edjee@google.com>
Trybot-Ready: Edward Jee <edjee@google.com>
diff --git a/grub-lakitu/grub-core/commands/verify_helper.c b/grub-lakitu/grub-core/commands/verify_helper.c
index 11d84a1..5a55927 100644
--- a/grub-lakitu/grub-core/commands/verify_helper.c
+++ b/grub-lakitu/grub-core/commands/verify_helper.c
@@ -161,6 +161,20 @@
return NULL;
}
+grub_err_t
+grub_verify_string (char *str, enum grub_verify_string_type type)
+{
+ struct grub_file_verifier *ver;
+ FOR_LIST_ELEMENTS(ver, grub_file_verifiers)
+ {
+ grub_err_t err;
+ err = ver->verify_string ? ver->verify_string (str, type) : GRUB_ERR_NONE;
+ if (err)
+ return err;
+ }
+ return GRUB_ERR_NONE;
+}
+
GRUB_MOD_INIT(verify_helper)
{
grub_file_filter_register (GRUB_FILE_FILTER_VERIFY, grub_verify_helper_open);
diff --git a/grub-lakitu/grub-core/lib/cmdline.c b/grub-lakitu/grub-core/lib/cmdline.c
index d5e10ee..ed0b149 100644
--- a/grub-lakitu/grub-core/lib/cmdline.c
+++ b/grub-lakitu/grub-core/lib/cmdline.c
@@ -62,12 +62,13 @@
return size;
}
-int grub_create_loader_cmdline (int argc, char *argv[], char *buf,
- grub_size_t size)
+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;
unsigned int arg_size;
- char *c;
+ char *c, *orig_buf = buf;
for (i = 0; i < argc; i++)
{
@@ -104,5 +105,5 @@
*buf = 0;
- return i;
+ return grub_verify_string (orig_buf, type);
}
diff --git a/grub-lakitu/grub-core/loader/arm/linux.c b/grub-lakitu/grub-core/loader/arm/linux.c
index 260cbf0..f45bb1c 100644
--- a/grub-lakitu/grub-core/loader/arm/linux.c
+++ b/grub-lakitu/grub-core/loader/arm/linux.c
@@ -28,6 +28,7 @@
#include <grub/cpu/linux.h>
#include <grub/lib/cmdline.h>
#include <grub/linux.h>
+#include <grub/verify.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -399,8 +400,11 @@
/* Create kernel command line. */
grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
- grub_create_loader_cmdline (argc, argv,
- linux_args + sizeof (LINUX_IMAGE) - 1, size);
+ err = grub_create_loader_cmdline (argc, argv,
+ linux_args + sizeof (LINUX_IMAGE) - 1, size,
+ GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ goto fail;
return GRUB_ERR_NONE;
diff --git a/grub-lakitu/grub-core/loader/arm64/linux.c b/grub-lakitu/grub-core/loader/arm64/linux.c
index 9519d2e..70dc195 100644
--- a/grub-lakitu/grub-core/loader/arm64/linux.c
+++ b/grub-lakitu/grub-core/loader/arm64/linux.c
@@ -31,6 +31,7 @@
#include <grub/efi/pe32.h>
#include <grub/i18n.h>
#include <grub/lib/cmdline.h>
+#include <grub/verify.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -305,9 +306,12 @@
goto fail;
}
grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
- grub_create_loader_cmdline (argc, argv,
- linux_args + sizeof (LINUX_IMAGE) - 1,
- cmdline_size);
+ err = grub_create_loader_cmdline (argc, argv,
+ linux_args + sizeof (LINUX_IMAGE) - 1,
+ cmdline_size,
+ GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ goto fail;
if (grub_errno == GRUB_ERR_NONE)
{
diff --git a/grub-lakitu/grub-core/loader/i386/bsd.c b/grub-lakitu/grub-core/loader/i386/bsd.c
index d34da14..c26edb4 100644
--- a/grub-lakitu/grub-core/loader/i386/bsd.c
+++ b/grub-lakitu/grub-core/loader/i386/bsd.c
@@ -35,6 +35,7 @@
#include <grub/ns8250.h>
#include <grub/bsdlabel.h>
#include <grub/crypto.h>
+#include <grub/verify.h>
#ifdef GRUB_MACHINE_PCBIOS
#include <grub/machine/int.h>
#endif
@@ -416,6 +417,8 @@
grub_addr_t addr, grub_uint32_t size)
{
const char *name;
+ grub_err_t err;
+
name = grub_strrchr (filename, '/');
if (name)
name++;
@@ -469,6 +472,9 @@
*(p++) = ' ';
}
*p = 0;
+ err = grub_verify_string (cmdline, GRUB_VERIFY_MODULE_CMDLINE);
+ if (err)
+ return err;
}
}
diff --git a/grub-lakitu/grub-core/loader/i386/linux.c b/grub-lakitu/grub-core/loader/i386/linux.c
index 7ec71ab..2f3e082 100644
--- a/grub-lakitu/grub-core/loader/i386/linux.c
+++ b/grub-lakitu/grub-core/loader/i386/linux.c
@@ -1012,11 +1012,17 @@
if (!linux_cmdline)
goto fail;
grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
- grub_create_loader_cmdline (argc, argv,
- linux_cmdline
- + sizeof (LINUX_IMAGE) - 1,
- maximal_cmdline_size
- - (sizeof (LINUX_IMAGE) - 1));
+ {
+ grub_err_t err;
+ err = grub_create_loader_cmdline (argc, argv,
+ linux_cmdline
+ + sizeof (LINUX_IMAGE) - 1,
+ maximal_cmdline_size
+ - (sizeof (LINUX_IMAGE) - 1),
+ GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ goto fail;
+ }
len = prot_file_size;
if (grub_file_read (file, prot_mode_mem, len) != len && !grub_errno)
diff --git a/grub-lakitu/grub-core/loader/i386/multiboot_mbi.c b/grub-lakitu/grub-core/loader/i386/multiboot_mbi.c
index fd7b41b..2bcf01d 100644
--- a/grub-lakitu/grub-core/loader/i386/multiboot_mbi.c
+++ b/grub-lakitu/grub-core/loader/i386/multiboot_mbi.c
@@ -673,10 +673,8 @@
return grub_errno;
cmdline_size = len;
- grub_create_loader_cmdline (argc, argv, cmdline,
- cmdline_size);
-
- return GRUB_ERR_NONE;
+ return grub_create_loader_cmdline (argc, argv, cmdline,
+ cmdline_size, GRUB_VERIFY_KERNEL_CMDLINE);
}
grub_err_t
@@ -685,6 +683,7 @@
{
struct module *newmod;
grub_size_t len = 0;
+ grub_err_t err;
newmod = grub_malloc (sizeof (*newmod));
if (!newmod)
@@ -704,8 +703,13 @@
newmod->cmdline_size = len;
total_modcmd += ALIGN_UP (len, 4);
- grub_create_loader_cmdline (argc, argv, newmod->cmdline,
- newmod->cmdline_size);
+ err = grub_create_loader_cmdline (argc, argv, newmod->cmdline,
+ newmod->cmdline_size, GRUB_VERIFY_MODULE_CMDLINE);
+ if (err)
+ {
+ grub_free (newmod);
+ return grub_errno;
+ }
if (modules_last)
modules_last->next = newmod;
diff --git a/grub-lakitu/grub-core/loader/i386/pc/linux.c b/grub-lakitu/grub-core/loader/i386/pc/linux.c
index ae769bb..89c6a74 100644
--- a/grub-lakitu/grub-core/loader/i386/pc/linux.c
+++ b/grub-lakitu/grub-core/loader/i386/pc/linux.c
@@ -334,11 +334,14 @@
/* Create kernel command line. */
grub_memcpy ((char *)grub_linux_real_chunk + GRUB_LINUX_CL_OFFSET,
LINUX_IMAGE, sizeof (LINUX_IMAGE));
- grub_create_loader_cmdline (argc, argv,
- (char *)grub_linux_real_chunk
- + GRUB_LINUX_CL_OFFSET + sizeof (LINUX_IMAGE) - 1,
- maximal_cmdline_size
- - (sizeof (LINUX_IMAGE) - 1));
+ err = grub_create_loader_cmdline (argc, argv,
+ (char *)grub_linux_real_chunk
+ + GRUB_LINUX_CL_OFFSET + sizeof (LINUX_IMAGE) - 1,
+ maximal_cmdline_size
+ - (sizeof (LINUX_IMAGE) - 1),
+ GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ goto fail;
if (grub_linux_is_bzimage)
grub_linux_prot_target = GRUB_LINUX_BZIMAGE_ADDR;
diff --git a/grub-lakitu/grub-core/loader/i386/pc/plan9.c b/grub-lakitu/grub-core/loader/i386/pc/plan9.c
index 0351090..3755015 100644
--- a/grub-lakitu/grub-core/loader/i386/pc/plan9.c
+++ b/grub-lakitu/grub-core/loader/i386/pc/plan9.c
@@ -33,6 +33,7 @@
#include <grub/mm.h>
#include <grub/cpu/relocator.h>
#include <grub/extcmd.h>
+#include <grub/verify.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -505,6 +506,7 @@
configptr = grub_stpcpy (configptr, "bootfile=");
configptr = grub_stpcpy (configptr, bootpath);
*configptr++ = '\n';
+ char *cmdline = configptr;
{
int i;
for (i = 1; i < argc; i++)
@@ -513,6 +515,15 @@
*configptr++ = '\n';
}
}
+
+ {
+ grub_err_t err;
+ *configptr = '\0';
+ err = grub_verify_string (cmdline, GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ goto fail;
+ }
+
configptr = grub_stpcpy (configptr, fill_ctx.pmap);
{
diff --git a/grub-lakitu/grub-core/loader/i386/xen.c b/grub-lakitu/grub-core/loader/i386/xen.c
index 85cc8d9..5b5968e 100644
--- a/grub-lakitu/grub-core/loader/i386/xen.c
+++ b/grub-lakitu/grub-core/loader/i386/xen.c
@@ -40,6 +40,7 @@
#include <grub/xen_file.h>
#include <grub/linux.h>
#include <grub/i386/memory.h>
+#include <grub/verify.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -647,6 +648,9 @@
grub_create_loader_cmdline (argc - 1, argv + 1,
(char *) xen_state.next_start.cmd_line,
sizeof (xen_state.next_start.cmd_line) - 1);
+ err = grub_verify_string (xen_state.next_start.cmd_line, GRUB_VERIFY_MODULE_CMDLINE);
+ if (err)
+ return err;
file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
if (!file)
@@ -908,6 +912,9 @@
grub_create_loader_cmdline (argc - 1, argv + 1,
get_virtual_current_address (ch), cmdline_len);
+ err = grub_verify_string (get_virtual_current_address (ch), GRUB_VERIFY_MODULE_CMDLINE);
+ if (err)
+ goto fail;
xen_state.module_info_page[xen_state.n_modules].cmdline =
xen_state.max_addr - xen_state.modules_target_start;
diff --git a/grub-lakitu/grub-core/loader/ia64/efi/linux.c b/grub-lakitu/grub-core/loader/ia64/efi/linux.c
index efaa42c..435e4e8 100644
--- a/grub-lakitu/grub-core/loader/ia64/efi/linux.c
+++ b/grub-lakitu/grub-core/loader/ia64/efi/linux.c
@@ -33,6 +33,7 @@
#include <grub/i18n.h>
#include <grub/env.h>
#include <grub/linux.h>
+#include <grub/verify.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -543,6 +544,12 @@
p = grub_stpcpy (p, argv[i]);
}
cmdline[10] = '=';
+
+ *p = '\0';
+
+ err = grub_verify_string (cmdline, GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ goto fail;
boot_param->command_line = (grub_uint64_t) cmdline;
boot_param->efi_systab = (grub_uint64_t) grub_efi_system_table;
diff --git a/grub-lakitu/grub-core/loader/mips/linux.c b/grub-lakitu/grub-core/loader/mips/linux.c
index 7b28ba7..e256c44 100644
--- a/grub-lakitu/grub-core/loader/mips/linux.c
+++ b/grub-lakitu/grub-core/loader/mips/linux.c
@@ -327,6 +327,8 @@
linux_argv++;
linux_args += ALIGN_UP (sizeof ("a0"), 4);
+ char *params = linux_args;
+
#ifdef GRUB_MACHINE_MIPS_LOONGSON
{
unsigned mtype = grub_arch_machine;
@@ -352,6 +354,12 @@
linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4);
}
+ *linux_args = '\0';
+
+ err = grub_verify_string (params, GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ return err;
+
/* Reserve space for rd arguments. */
rd_addr_arg_off = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground;
linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4);
diff --git a/grub-lakitu/grub-core/loader/multiboot.c b/grub-lakitu/grub-core/loader/multiboot.c
index 0730e47..084c9c4 100644
--- a/grub-lakitu/grub-core/loader/multiboot.c
+++ b/grub-lakitu/grub-core/loader/multiboot.c
@@ -313,7 +313,9 @@
grub_dl_ref (my_mod);
/* Skip filename. */
- grub_multiboot_init_mbi (argc - 1, argv + 1);
+ err = grub_multiboot_init_mbi (argc - 1, argv + 1);
+ if (err)
+ goto fail;
grub_relocator_unload (grub_multiboot_relocator);
grub_multiboot_relocator = grub_relocator_new ();
diff --git a/grub-lakitu/grub-core/loader/multiboot_mbi2.c b/grub-lakitu/grub-core/loader/multiboot_mbi2.c
index b0679a9..c514bad 100644
--- a/grub-lakitu/grub-core/loader/multiboot_mbi2.c
+++ b/grub-lakitu/grub-core/loader/multiboot_mbi2.c
@@ -1074,10 +1074,8 @@
return grub_errno;
cmdline_size = len;
- grub_create_loader_cmdline (argc, argv, cmdline,
- cmdline_size);
-
- return GRUB_ERR_NONE;
+ return grub_create_loader_cmdline (argc, argv, cmdline, cmdline_size,
+ GRUB_VERIFY_KERNEL_CMDLINE);
}
grub_err_t
@@ -1086,6 +1084,7 @@
{
struct module *newmod;
grub_size_t len = 0;
+ grub_err_t err;
newmod = grub_malloc (sizeof (*newmod));
if (!newmod)
@@ -1104,8 +1103,10 @@
newmod->cmdline_size = len;
total_modcmd += ALIGN_UP (len, MULTIBOOT_TAG_ALIGN);
- grub_create_loader_cmdline (argc, argv, newmod->cmdline,
- newmod->cmdline_size);
+ err = grub_create_loader_cmdline (argc, argv, newmod->cmdline,
+ newmod->cmdline_size, GRUB_VERIFY_MODULE_CMDLINE);
+ if (err)
+ return err;
if (modules_last)
modules_last->next = newmod;
diff --git a/grub-lakitu/grub-core/loader/powerpc/ieee1275/linux.c b/grub-lakitu/grub-core/loader/powerpc/ieee1275/linux.c
index 6e81464..c114e7d 100644
--- a/grub-lakitu/grub-core/loader/powerpc/ieee1275/linux.c
+++ b/grub-lakitu/grub-core/loader/powerpc/ieee1275/linux.c
@@ -302,8 +302,9 @@
/* Create kernel command line. */
grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
- grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1,
- size);
+ if (grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1,
+ size))
+ goto out;
out:
diff --git a/grub-lakitu/grub-core/loader/sparc64/ieee1275/linux.c b/grub-lakitu/grub-core/loader/sparc64/ieee1275/linux.c
index 67ef048..abe46fa 100644
--- a/grub-lakitu/grub-core/loader/sparc64/ieee1275/linux.c
+++ b/grub-lakitu/grub-core/loader/sparc64/ieee1275/linux.c
@@ -340,8 +340,9 @@
/* Create kernel command line. */
grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
- grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1,
- size);
+ if (grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1,
+ size, GRUB_VERIFY_KERNEL_CMDLINE))
+ goto out;
out:
if (elf)
diff --git a/grub-lakitu/grub-core/loader/xnu.c b/grub-lakitu/grub-core/loader/xnu.c
index 84c8b93..ff66be4 100644
--- a/grub-lakitu/grub-core/loader/xnu.c
+++ b/grub-lakitu/grub-core/loader/xnu.c
@@ -33,6 +33,7 @@
#include <grub/extcmd.h>
#include <grub/env.h>
#include <grub/i18n.h>
+#include <grub/verify.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -425,6 +426,10 @@
if (ptr != grub_xnu_cmdline)
*(ptr - 1) = 0;
+ err = grub_verify_string (grub_xnu_cmdline, GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ return err;
+
#if defined (__i386) && !defined (GRUB_MACHINE_EFI)
err = grub_efiemu_autocore ();
if (err)
@@ -534,6 +539,10 @@
if (ptr != grub_xnu_cmdline)
*(ptr - 1) = 0;
+ err = grub_verify_string (grub_xnu_cmdline, GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ return err;
+
#if defined (__i386) && !defined (GRUB_MACHINE_EFI)
err = grub_efiemu_autocore ();
if (err)
diff --git a/grub-lakitu/include/grub/lib/cmdline.h b/grub-lakitu/include/grub/lib/cmdline.h
index 1fe8d01..cdca09b 100644
--- a/grub-lakitu/include/grub/lib/cmdline.h
+++ b/grub-lakitu/include/grub/lib/cmdline.h
@@ -21,11 +21,12 @@
#define GRUB_CMDLINE_HEADER 1
#include <grub/types.h>
+#include <grub/verify.h>
#define LINUX_IMAGE "BOOT_IMAGE="
unsigned int grub_loader_cmdline_size (int argc, char *argv[]);
-int grub_create_loader_cmdline (int argc, char *argv[], char *buf,
- grub_size_t size);
+grub_err_t grub_create_loader_cmdline (int argc, char *argv[], char *buf,
+ grub_size_t size, enum grub_verify_string_type type);
#endif /* ! GRUB_CMDLINE_HEADER */
diff --git a/grub-lakitu/include/grub/verify.h b/grub-lakitu/include/grub/verify.h
index 4598a7e..acab4f4 100644
--- a/grub-lakitu/include/grub/verify.h
+++ b/grub-lakitu/include/grub/verify.h
@@ -7,6 +7,12 @@
GRUB_VERIFY_FLAGS_SINGLE_CHUNK = 2,
};
+enum grub_verify_string_type
+ {
+ GRUB_VERIFY_KERNEL_CMDLINE,
+ GRUB_VERIFY_MODULE_CMDLINE,
+ };
+
struct grub_file_verifier
{
struct grub_file_verifier *next;
@@ -25,6 +31,8 @@
grub_err_t (*write) (void *context, void *buf, grub_size_t sz);
grub_err_t (*fini) (void *context);
void (*close) (void *context);
+
+ grub_err_t (*verify_string) (char *str, enum grub_verify_string_type type);
};
extern struct grub_file_verifier *grub_file_verifiers;
@@ -40,3 +48,6 @@
{
grub_list_remove (GRUB_AS_LIST (ver));
}
+
+grub_err_t
+grub_verify_string (char *str, enum grub_verify_string_type type);