multiboot1: Add bounds validation for ELF section headers

This commit is contained in:
Mintsuki 2026-01-13 05:11:25 +01:00
parent 176c01e7a7
commit 8133a5b0b6
No known key found for this signature in database
GPG Key ID: 1F3C021BECA23821

View File

@ -216,16 +216,21 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
mb1_info_alloc(&mb1_info_raw, sizeof(struct multiboot1_info));
if (section_hdr_info_valid == true) {
size_t section_table_size = (size_t)section_hdr_info.section_entry_size * section_hdr_info.num;
if (section_hdr_info.section_offset > kernel_file_size ||
section_table_size > kernel_file_size - section_hdr_info.section_offset) {
panic(true, "multiboot1: ELF section headers out of bounds");
}
multiboot1_info->elf_sect.num = section_hdr_info.num;
multiboot1_info->elf_sect.size = section_hdr_info.section_entry_size;
multiboot1_info->elf_sect.shndx = section_hdr_info.str_section_idx;
void *sections = mb1_info_alloc(&mb1_info_raw,
section_hdr_info.section_entry_size * section_hdr_info.num);
void *sections = mb1_info_alloc(&mb1_info_raw, section_table_size);
multiboot1_info->elf_sect.addr = (uintptr_t)sections - mb1_info_slide;
memcpy(sections, kernel + section_hdr_info.section_offset, section_hdr_info.section_entry_size * section_hdr_info.num);
memcpy(sections, kernel + section_hdr_info.section_offset, section_table_size);
int bits = elf_bits(kernel);
@ -237,6 +242,11 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
continue;
}
if (shdr->sh_offset > kernel_file_size ||
shdr->sh_size > kernel_file_size - shdr->sh_offset) {
continue;
}
uint64_t section = (uint64_t)-1; /* no target preference, use top */
if (!elsewhere_append(true /* flexible target */,
@ -253,6 +263,11 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
continue;
}
if (shdr->sh_offset > kernel_file_size ||
shdr->sh_size > kernel_file_size - shdr->sh_offset) {
continue;
}
uint64_t section = (uint64_t)-1; /* no target preference, use top */
if (!elsewhere_append(true /* flexible target */,
@ -260,7 +275,7 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
kernel + shdr->sh_offset, &section, shdr->sh_size)) {
panic(true, "multiboot1: Cannot allocate elf sections");
}
shdr->sh_addr = section;
}
}