multiboot1,multiboot2: Add bounds check to header search
diff --git a/common/protos/multiboot1.c b/common/protos/multiboot1.c
index 9114f7bd..791fc0cb 100644
--- a/common/protos/multiboot1.c
+++ b/common/protos/multiboot1.c
@@ -73,8 +73,18 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
struct multiboot1_header header = {0};
size_t header_offset = 0;
- for (header_offset = 0; header_offset < 8192; header_offset += 4) {
- uint32_t v = *(uint32_t *)(kernel+header_offset);
+ // Per Multiboot spec, header must be within first 8192 bytes and 4-byte aligned.
+ // Ensure we don't read past end of file when checking magic or copying header.
+ size_t search_limit = 8192;
+ if (kernel_file_size < sizeof(struct multiboot1_header)) {
+ panic(true, "multiboot1: Kernel file too small to contain header");
+ }
+ if (search_limit > kernel_file_size - sizeof(struct multiboot1_header)) {
+ search_limit = kernel_file_size - sizeof(struct multiboot1_header);
+ }
+
+ for (header_offset = 0; header_offset <= search_limit; header_offset += 4) {
+ uint32_t v = *(uint32_t *)(kernel + header_offset);
if (v == MULTIBOOT1_HEADER_MAGIC) {
memcpy(&header, kernel + header_offset, sizeof(header));
diff --git a/common/protos/multiboot2.c b/common/protos/multiboot2.c
index e4acbf7e..59331257 100644
--- a/common/protos/multiboot2.c
+++ b/common/protos/multiboot2.c
@@ -90,9 +90,19 @@ noreturn void multiboot2_load(char *config, char* cmdline) {
fclose(kernel_file);
- struct multiboot_header *header;
+ struct multiboot_header *header = NULL;
- for (size_t header_offset = 0; header_offset < MULTIBOOT_SEARCH; header_offset += MULTIBOOT_HEADER_ALIGN) {
+ // Per Multiboot2 spec, header must be within first 32768 bytes and 8-byte aligned.
+ // Ensure we don't read past end of file when checking magic.
+ size_t search_limit = MULTIBOOT_SEARCH;
+ if (kernel_file_size < sizeof(struct multiboot_header)) {
+ panic(true, "multiboot2: Kernel file too small to contain header");
+ }
+ if (search_limit > kernel_file_size - sizeof(struct multiboot_header)) {
+ search_limit = kernel_file_size - sizeof(struct multiboot_header);
+ }
+
+ for (size_t header_offset = 0; header_offset <= search_limit; header_offset += MULTIBOOT_HEADER_ALIGN) {
header = (void *)(kernel + header_offset);
if (header->magic == MULTIBOOT2_HEADER_MAGIC) {
@@ -100,7 +110,7 @@ noreturn void multiboot2_load(char *config, char* cmdline) {
}
}
- if (header->magic != MULTIBOOT2_HEADER_MAGIC) {
+ if (header == NULL || header->magic != MULTIBOOT2_HEADER_MAGIC) {
panic(true, "multiboot2: Invalid magic");
}
