From dab6a0f0c31d2805fff1f58e5c37e21260602b6b Mon Sep 17 00:00:00 2001 From: Michael Marineau Date: Wed, 19 Oct 2016 14:12:55 -0700 Subject: [PATCH] loader: validate cmdline string length before appending verity arg --- grub-core/loader/i386/efi/linux.c | 2 +- grub-core/loader/i386/linux.c | 2 +- grub-core/loader/i386/verity-hash.h | 14 ++++++++++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c index e572d2351..d195c59bf 100644 --- a/grub-core/loader/i386/efi/linux.c +++ b/grub-core/loader/i386/efi/linux.c @@ -286,7 +286,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), linux_cmdline + sizeof (LINUX_IMAGE) - 1, lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1)); - grub_pass_verity_hash(&lh, linux_cmdline); + grub_pass_verity_hash(&lh, linux_cmdline, lh.cmdline_size); lh.cmd_line_ptr = (grub_uint32_t)(grub_uint64_t)linux_cmdline; handover_offset = lh.handover_offset; diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index 7f92c363a..84ec8e241 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -1029,7 +1029,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), maximal_cmdline_size - (sizeof (LINUX_IMAGE) - 1)); - grub_pass_verity_hash(&lh, linux_cmdline); + grub_pass_verity_hash(&lh, linux_cmdline, maximal_cmdline_size); len = prot_file_size; grub_memcpy (prot_mode_mem, kernel + kernel_offset, len); kernel_offset += len; diff --git a/grub-core/loader/i386/verity-hash.h b/grub-core/loader/i386/verity-hash.h index 4027be6aa..afbfd14d6 100644 --- a/grub-core/loader/i386/verity-hash.h +++ b/grub-core/loader/i386/verity-hash.h @@ -1,9 +1,11 @@ #define VERITY_ARG " verity.usrhash=" +#define VERITY_ARG_LENGTH (sizeof (VERITY_ARG) - 1) #define VERITY_HASH_OFFSET 0x40 #define VERITY_HASH_LENGTH 64 static inline void grub_pass_verity_hash(struct linux_kernel_header *lh, - char *cmdline) + char *cmdline, + grub_size_t cmdline_max_len) { char *buf = (char *)lh; grub_size_t cmdline_len; @@ -16,10 +18,14 @@ static inline void grub_pass_verity_hash(struct linux_kernel_header *lh, return; } - grub_memcpy (cmdline + grub_strlen(cmdline), VERITY_ARG, - sizeof (VERITY_ARG)); cmdline_len = grub_strlen(cmdline); + if (cmdline_len + VERITY_ARG_LENGTH + VERITY_HASH_LENGTH > cmdline_max_len) + return; + + grub_memcpy (cmdline + cmdline_len, VERITY_ARG, VERITY_ARG_LENGTH); + cmdline_len += VERITY_ARG_LENGTH; grub_memcpy (cmdline + cmdline_len, buf + VERITY_HASH_OFFSET, VERITY_HASH_LENGTH); - cmdline[cmdline_len + VERITY_HASH_LENGTH] = '\0'; + cmdline_len += VERITY_HASH_LENGTH; + cmdline[cmdline_len] = '\0'; }