changeset 10304:af5a60358231

6691145 multiboot header in the 32-bit kernel includes the AOUT_KLUDGE flag 6870749 multiboot modules array may exist outside the boot memory area, inducing panic
author Seth Goldberg <Seth.Goldberg@Sun.COM>
date Thu, 13 Aug 2009 15:30:27 -0700
parents 3b9249b9e2fc
children f6df05de8700
files usr/src/uts/common/sys/multiboot.h usr/src/uts/i86pc/dboot/dboot_grub.s usr/src/uts/i86pc/dboot/dboot_startkern.c usr/src/uts/i86pc/os/fakebop.c
diffstat 4 files changed, 38 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/sys/multiboot.h	Thu Aug 13 13:11:48 2009 -0700
+++ b/usr/src/uts/common/sys/multiboot.h	Thu Aug 13 15:30:27 2009 -0700
@@ -35,8 +35,13 @@
  * Definitions of structures/data for using a multiboot compliant OS loader.
  */
 #define	MB_HEADER_MAGIC		 0x1BADB002	/* magic */
-#define	MB_HEADER_FLAGS		 0x00010003	/* flags we use */
-#define	MB_HEADER_CHECKSUM	-0x1BAEB005	/* -(magic + flag) */
+
+/* The 32-bit kernel does not require the use of the AOUT kludge */
+#define	MB_HEADER_FLAGS_32	 0x00000003	/* flags we use */
+#define	MB_HEADER_CHECKSUM_32	-0x1BADB005	/* -(magic + flag) */
+
+#define	MB_HEADER_FLAGS_64	 0x00010003	/* flags we use */
+#define	MB_HEADER_CHECKSUM_64	-0x1BAEB005	/* -(magic + flag) */
 
 /*
  * passed by boot loader to kernel
--- a/usr/src/uts/i86pc/dboot/dboot_grub.s	Thu Aug 13 13:11:48 2009 -0700
+++ b/usr/src/uts/i86pc/dboot/dboot_grub.s	Thu Aug 13 15:30:27 2009 -0700
@@ -21,7 +21,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -57,13 +57,20 @@
 	.globl	mb_header
 mb_header:
 	.long	MB_HEADER_MAGIC	/* magic number */
-	.long	MB_HEADER_FLAGS	/* flags */
-	.long	MB_HEADER_CHECKSUM	/* checksum */
-	.long	0x11111111	/* header_addr: patched by elfpatch */
-	.long	0x100000	/* load_addr: patched by elfpatch */
+#if defined(_BOOT_TARGET_i386)
+	.long	MB_HEADER_FLAGS_32	/* flags */
+	.long	MB_HEADER_CHECKSUM_32	/* checksum */
+#elif defined (_BOOT_TARGET_amd64)
+	.long	MB_HEADER_FLAGS_64	/* flags */
+	.long	MB_HEADER_CHECKSUM_64	/* checksum */
+#else
+#error No architecture defined
+#endif
+	.long	0x11111111	/* header_addr: patched by mbh_patch */
+	.long	0x100000	/* load_addr: patched by mbh_patch */
 	.long	0		/* load_end_addr - 0 means entire file */
 	.long	0		/* bss_end_addr */
-	.long	0x2222222	/* entry_addr: patched by elfpatch */
+	.long	0x2222222	/* entry_addr: patched by mbh_patch */
 	.long	0		/* video mode.. */
 	.long	0		/* width 0 == don't care */
 	.long	0		/* height 0 == don't care */
--- a/usr/src/uts/i86pc/dboot/dboot_startkern.c	Thu Aug 13 13:11:48 2009 -0700
+++ b/usr/src/uts/i86pc/dboot/dboot_startkern.c	Thu Aug 13 15:30:27 2009 -0700
@@ -799,6 +799,10 @@
 	DBG_MSG("Entered init_mem_alloc()\n");
 	DBG((uintptr_t)mb_info);
 
+	if (mb_info->mods_count > MAX_MODULES) {
+		dboot_panic("Too many modules (%d) -- the maximum is %d.",
+		    mb_info->mods_count, MAX_MODULES);
+	}
 	/*
 	 * search the modules to find the last used address
 	 * we'll build the module list while we're walking through here
@@ -814,7 +818,11 @@
 			    (ulong_t)mod->mod_start, (ulong_t)mod->mod_end);
 		}
 		modules[i].bm_addr = mod->mod_start;
-		modules[i].bm_size = mod->mod_end;
+		if (mod->mod_start > mod->mod_end) {
+			dboot_panic("module[%d]: Invalid module start address "
+			    "(0x%llx)", i, (uint64_t)mod->mod_start);
+		}
+		modules[i].bm_size = mod->mod_end - mod->mod_start;
 
 		check_higher(mod->mod_end);
 	}
--- a/usr/src/uts/i86pc/os/fakebop.c	Thu Aug 13 13:11:48 2009 -0700
+++ b/usr/src/uts/i86pc/os/fakebop.c	Thu Aug 13 15:30:27 2009 -0700
@@ -1087,9 +1087,9 @@
  * Fast Reboot.
  */
 static void
-save_boot_info(multiboot_info_t *mbi)
+save_boot_info(multiboot_info_t *mbi, struct xboot_info *xbi)
 {
-	mb_module_t *mbp;
+	struct boot_modules *modp;
 	int i;
 
 	bcopy(mbi, &saved_mbi, sizeof (multiboot_info_t));
@@ -1115,12 +1115,14 @@
 	/*
 	 * Current file sizes.  Used by fastboot.c to figure out how much
 	 * memory to reserve for panic reboot.
+	 * Use the module list from the dboot-constructed xboot_info
+	 * instead of the list referenced by the multiboot structure
+	 * because that structure may not be addressable now.
 	 */
 	saved_file_size[FASTBOOT_NAME_UNIX] = FOUR_MEG - PAGESIZE;
-	for (i = 0, mbp = (mb_module_t *)(uintptr_t)mbi->mods_addr;
-	    i < mbi->mods_count; i++, mbp += sizeof (mb_module_t)) {
-		saved_file_size[FASTBOOT_NAME_BOOTARCHIVE] +=
-		    mbp->mod_end - mbp->mod_start;
+	for (i = 0, modp = (struct boot_modules *)(uintptr_t)xbi->bi_modules;
+	    i < xbi->bi_module_cnt; i++, modp++) {
+		saved_file_size[FASTBOOT_NAME_BOOTARCHIVE] += modp->bm_size;
 	}
 
 }
@@ -1379,7 +1381,7 @@
 	/*
 	 * Save various boot information for Fast Reboot
 	 */
-	save_boot_info(mbi);
+	save_boot_info(mbi, xbootp);
 
 	if (mbi != NULL && mbi->flags & 0x2) {
 		boot_device = mbi->boot_device >> 24;