mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-27 03:33:50 +00:00
vbutil_kernel: copy zeropage fully
When copying the vmlinuz zeropage, the entries were being truncated even though the boot protocol version was being retained. This means that booting a kernel that depended on details from the zeropage's ignored areas would find invalid information. Fix this by copying out the entire possible range of memory. BUG=chromium:230212 TEST=kernels can boot with CONFIG_RELOCATABLE BRANCH=None Change-Id: Ifb94bedcf881e17ab20fff44d8c1c1885b15ef9e Signed-off-by: Kees Cook <keescook@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/47832 Reviewed-by: Luigi Semenzato <semenzato@chromium.org> Reviewed-by: Bill Richardson <wfrichar@chromium.org>
This commit is contained in:
@@ -23,14 +23,6 @@
|
|||||||
// RAM address where the 32-bit kernel expects to be started
|
// RAM address where the 32-bit kernel expects to be started
|
||||||
#define CROS_32BIT_ENTRY_ADDR 0x100000
|
#define CROS_32BIT_ENTRY_ADDR 0x100000
|
||||||
|
|
||||||
// Simplified version of the vmlinuz file header
|
|
||||||
struct linux_kernel_header
|
|
||||||
{
|
|
||||||
uint8_t pad0[0x01f1 - 0x0];
|
|
||||||
uint8_t setup_sects; // 1f1
|
|
||||||
uint8_t pad1[0x0230 - 0x1f2];
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
// Simplified version of x86 kernel e820 memory map entries
|
// Simplified version of x86 kernel e820 memory map entries
|
||||||
#define E820_ENTRY_MAX 128
|
#define E820_ENTRY_MAX 128
|
||||||
#define E820_TYPE_RAM 1
|
#define E820_TYPE_RAM 1
|
||||||
@@ -51,14 +43,21 @@ struct linux_kernel_params
|
|||||||
uint8_t setup_sects; // 1f1
|
uint8_t setup_sects; // 1f1
|
||||||
uint8_t pad2[0x1fe - 0x1f2];
|
uint8_t pad2[0x1fe - 0x1f2];
|
||||||
uint16_t boot_flag; // 1fe
|
uint16_t boot_flag; // 1fe
|
||||||
uint8_t pad3[0x210 - 0x200];
|
uint16_t jump; // 200
|
||||||
|
uint32_t header; // 202
|
||||||
|
uint16_t version; // 206
|
||||||
|
uint8_t pad3[0x210 - 0x208];
|
||||||
uint8_t type_of_loader; // 210
|
uint8_t type_of_loader; // 210
|
||||||
uint8_t pad4[0x218 - 0x211];
|
uint8_t pad4[0x218 - 0x211];
|
||||||
uint32_t ramdisk_image; // 218
|
uint32_t ramdisk_image; // 218
|
||||||
uint32_t ramdisk_size; // 21c
|
uint32_t ramdisk_size; // 21c
|
||||||
uint8_t pad5[0x228 - 0x220];
|
uint8_t pad5[0x228 - 0x220];
|
||||||
uint32_t cmd_line_ptr; // 228
|
uint32_t cmd_line_ptr; // 228
|
||||||
uint8_t pad6[0x2d0 - 0x22c];
|
uint32_t ramdisk_max; // 22c
|
||||||
|
uint32_t kernel_alignment; // 230
|
||||||
|
uint8_t relocatable_kernel; // 234
|
||||||
|
uint8_t min_alignment; // 235
|
||||||
|
uint8_t pad6[0x2d0 - 0x236];
|
||||||
struct linux_kernel_e820entry e820_entries[E820_ENTRY_MAX]; // 2d0 - cd0
|
struct linux_kernel_e820entry e820_entries[E820_ENTRY_MAX]; // 2d0 - cd0
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
|||||||
@@ -271,8 +271,7 @@ static int ImportVmlinuzFile(const char *vmlinuz_file, arch_t arch,
|
|||||||
uint64_t kernel_size;
|
uint64_t kernel_size;
|
||||||
uint64_t kernel32_start = 0;
|
uint64_t kernel32_start = 0;
|
||||||
uint64_t kernel32_size = 0;
|
uint64_t kernel32_size = 0;
|
||||||
struct linux_kernel_header* lh = 0;
|
struct linux_kernel_params *params = NULL, *lh = NULL;
|
||||||
struct linux_kernel_params* params = 0;
|
|
||||||
|
|
||||||
/* Read the kernel */
|
/* Read the kernel */
|
||||||
Debug("Reading %s\n", vmlinuz_file);
|
Debug("Reading %s\n", vmlinuz_file);
|
||||||
@@ -298,7 +297,7 @@ static int ImportVmlinuzFile(const char *vmlinuz_file, arch_t arch,
|
|||||||
|
|
||||||
/* The first part of the x86 vmlinuz is a header, followed by a real-mode
|
/* The first part of the x86 vmlinuz is a header, followed by a real-mode
|
||||||
* boot stub. We only want the 32-bit part. */
|
* boot stub. We only want the 32-bit part. */
|
||||||
lh = (struct linux_kernel_header *)kernel_buf;
|
lh = (struct linux_kernel_params *)kernel_buf;
|
||||||
kernel32_start = (lh->setup_sects + 1) << 9;
|
kernel32_start = (lh->setup_sects + 1) << 9;
|
||||||
if (kernel32_start >= kernel_size)
|
if (kernel32_start >= kernel_size)
|
||||||
Fatal("Malformed kernel\n");
|
Fatal("Malformed kernel\n");
|
||||||
@@ -318,7 +317,8 @@ static int ImportVmlinuzFile(const char *vmlinuz_file, arch_t arch,
|
|||||||
* tweak a few fields for our purposes */
|
* tweak a few fields for our purposes */
|
||||||
params = (struct linux_kernel_params *)(g_param_data);
|
params = (struct linux_kernel_params *)(g_param_data);
|
||||||
Memcpy(&(params->setup_sects), &(lh->setup_sects),
|
Memcpy(&(params->setup_sects), &(lh->setup_sects),
|
||||||
sizeof(*lh) - offsetof(struct linux_kernel_header, setup_sects));
|
offsetof(struct linux_kernel_params, e820_entries)
|
||||||
|
- offsetof(struct linux_kernel_params, setup_sects));
|
||||||
params->boot_flag = 0;
|
params->boot_flag = 0;
|
||||||
params->ramdisk_image = 0; /* we don't support initrd */
|
params->ramdisk_image = 0; /* we don't support initrd */
|
||||||
params->ramdisk_size = 0;
|
params->ramdisk_size = 0;
|
||||||
@@ -329,6 +329,9 @@ static int ImportVmlinuzFile(const char *vmlinuz_file, arch_t arch,
|
|||||||
roundup(kernel32_size, CROS_ALIGN) +
|
roundup(kernel32_size, CROS_ALIGN) +
|
||||||
find_cmdline_start((char *)g_config_data, g_config_size);
|
find_cmdline_start((char *)g_config_data, g_config_size);
|
||||||
Debug(" cmdline_addr=0x%x\n", params->cmd_line_ptr);
|
Debug(" cmdline_addr=0x%x\n", params->cmd_line_ptr);
|
||||||
|
Debug(" version=0x%x\n", params->version);
|
||||||
|
Debug(" kernel_alignment=0x%x\n", params->kernel_alignment);
|
||||||
|
Debug(" relocatable_kernel=0x%x\n", params->relocatable_kernel);
|
||||||
/* A fake e820 memory map with 2 entries */
|
/* A fake e820 memory map with 2 entries */
|
||||||
params->n_e820_entry = 2;
|
params->n_e820_entry = 2;
|
||||||
params->e820_entries[0].start_addr = 0x00000000;
|
params->e820_entries[0].start_addr = 0x00000000;
|
||||||
|
|||||||
Reference in New Issue
Block a user