]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Add possibility to verify kernel command lines.
authorVladimir Serbinenko <phcoder@gmail.com>
Tue, 7 Feb 2017 01:10:14 +0000 (02:10 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Tue, 9 May 2017 14:12:18 +0000 (16:12 +0200)
19 files changed:
grub-core/commands/verify_helper.c
grub-core/lib/cmdline.c
grub-core/loader/arm/linux.c
grub-core/loader/arm64/linux.c
grub-core/loader/i386/bsd.c
grub-core/loader/i386/linux.c
grub-core/loader/i386/multiboot_mbi.c
grub-core/loader/i386/pc/linux.c
grub-core/loader/i386/pc/plan9.c
grub-core/loader/i386/xen.c
grub-core/loader/ia64/efi/linux.c
grub-core/loader/mips/linux.c
grub-core/loader/multiboot.c
grub-core/loader/multiboot_mbi2.c
grub-core/loader/powerpc/ieee1275/linux.c
grub-core/loader/sparc64/ieee1275/linux.c
grub-core/loader/xnu.c
include/grub/lib/cmdline.h
include/grub/verify.h

index 11d84a17f65d7b04f0c4356925fdcd454fb53b1b..5a55927e3ba6e30c1e97d582e96f0b60580b5db2 100644 (file)
@@ -161,6 +161,20 @@ grub_verify_helper_open (grub_file_t io, enum grub_file_type type)
   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);
index d5e10ee8798c856d640ec3a06fb42119eb5ab5fa..ed0b149dca55b84ba42b51049baa9f5205493d18 100644 (file)
@@ -62,12 +62,13 @@ unsigned int grub_loader_cmdline_size (int argc, char *argv[])
   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 @@ int grub_create_loader_cmdline (int argc, char *argv[], char *buf,
 
   *buf = 0;
 
-  return i;
+  return grub_verify_string (orig_buf, type);
 }
index 260cbf06861e7471d9e872ba60375fdfb44d0eec..f45bb1cef4a40b847b24e8b4d80c9c8bf606fae5 100644 (file)
@@ -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 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 
   /* 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;
 
index 9519d2e4d3ec1229a76eb4bce773c78c7af24a6e..70dc1954b6a7bc3e6dff4010a37111cca439322d 100644 (file)
@@ -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 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
       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)
     {
index d34da14d981593a5a27a571741dc515135886d95..c26edb4a9f33c259a358105ccde8eefe90e3aac3 100644 (file)
@@ -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_freebsd_add_meta_module (const char *filename, const char *type,
                              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 @@ grub_freebsd_add_meta_module (const char *filename, const char *type,
              *(p++) = ' ';
            }
          *p = 0;
+         err = grub_verify_string (cmdline, GRUB_VERIFY_MODULE_CMDLINE);
+         if (err)
+           return err;
        }
     }
 
index 7ec71abadcdb4508a4cfd633d3f155bf274fd19a..2f3e08263170192095529284c4abe9c50d885c0e 100644 (file)
@@ -1012,11 +1012,17 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   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)
index fd7b41b0cad4f26d1170d70692ac1ac27fd6bd73..2bcf01da3f048a9d1e0b31228696b610f2bbe0ec 100644 (file)
@@ -673,10 +673,8 @@ grub_multiboot_init_mbi (int argc, char *argv[])
     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 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
 {
   struct module *newmod;
   grub_size_t len = 0;
+  grub_err_t err;
 
   newmod = grub_malloc (sizeof (*newmod));
   if (!newmod)
@@ -704,8 +703,13 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
   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;
index ae769bb2eccbe5ffbe4a61dc94745961ebd33e27..89c6a74364830c88926a0cc24c0a200086cdd944 100644 (file)
@@ -334,11 +334,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   /* 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;
index 0351090daf813d1a653741fd424685ff9c4e77cd..37550155df782e1ffeacb7e64fca04bd4effdd0a 100644 (file)
@@ -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 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
   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 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
        *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);
 
   {
index 85cc8d93fc236bf7070d61044736afc422453b71..5b5968e940f7f644eb2743eed93abec08d0563cc 100644 (file)
@@ -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_cmd_xen (grub_command_t cmd __attribute__ ((unused)),
   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_cmd_module (grub_command_t cmd __attribute__ ((unused)),
 
   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;
index efaa42ccdd2bf74321de20cf5033a80676cc7dc3..435e4e8ae76d46736138750c522a4d8effec656d 100644 (file)
@@ -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 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
       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;
index 7b28ba73166928eb7cb5e87f47b7c63534552f14..e256c440f6c8e8b716e54c93a2711c9ab16b6649 100644 (file)
@@ -327,6 +327,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   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 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
       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);
index 0730e47c8ee7207030e7c2b45a051a62757faf67..084c9c45c43dec9e5b415f8e6d83c068a31e277b 100644 (file)
@@ -313,7 +313,9 @@ grub_cmd_multiboot (grub_command_t cmd __attribute__ ((unused)),
   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 ();
index b0679a9f6c9848d81cb74cf799ad3a7b235d937c..c514bad2a01971978873906edb616fc3a6f62148 100644 (file)
@@ -1074,10 +1074,8 @@ grub_multiboot_init_mbi (int argc, char *argv[])
     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 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
 {
   struct module *newmod;
   grub_size_t len = 0;
+  grub_err_t err;
 
   newmod = grub_malloc (sizeof (*newmod));
   if (!newmod)
@@ -1104,8 +1103,10 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
   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;
index 6e814649f319c197c61b67013da9e85d652f8f7b..c114e7df4fb7200823271ebae6a9dcbecbbf3028 100644 (file)
@@ -302,8 +302,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 
   /* 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:
 
index 67ef0488324f9bbbc69d78b31215a310e9beb70e..abe46faa0126aa88eb3f79f91019cef8849c99cc 100644 (file)
@@ -340,8 +340,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 
   /* 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)
index 84c8b939c8177e8da5fed9a18bcd2c39644fd227..ff66be4bf43fbaacd6569c2a469da73b7336cb81 100644 (file)
@@ -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 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
   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 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
   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)
index 1fe8d017971ba4091f26f9608296aaf2db1ca7f9..cdca09b7a164c0f22f04bddd52c4fc4f61ea1a56 100644 (file)
 #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 */
index 4598a7ebfaa14bca592b650252999a9e38e126fb..acab4f437a396077330ebee235609eafc0908c36 100644 (file)
@@ -7,6 +7,12 @@ enum grub_verify_flags
     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 @@ struct grub_file_verifier
   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_verifier_unregister (struct grub_file_verifier *ver)
 {
   grub_list_remove (GRUB_AS_LIST (ver));
 }
+
+grub_err_t
+grub_verify_string (char *str, enum grub_verify_string_type type);