[syslinux:pathbased] mboot.c32: handle non-self-terminating images

syslinux-bot for H. Peter Anvin hpa at linux.intel.com
Tue Jun 8 11:03:21 PDT 2010


Commit-ID:  ac968004da9f0003db92e9becca828c2685a24ad
Gitweb:     http://syslinux.zytor.com/commit/ac968004da9f0003db92e9becca828c2685a24ad
Author:     H. Peter Anvin <hpa at linux.intel.com>
AuthorDate: Tue, 8 Jun 2010 10:58:48 -0700
Committer:  H. Peter Anvin <hpa at linux.intel.com>
CommitDate: Tue, 8 Jun 2010 10:58:48 -0700

mboot.c32: handle non-self-terminating images

Handle non-ELF Multiboot images with 0 entries for data and/or bss
end, which means "until end of the file" and "nothing" for the two fields,
respectively.

Reported-and-tested-by: Thomas Bächler <thomas at archlinux.org>
Signed-off-by: H. Peter Anvin <hpa at linux.intel.com>


---
 com32/mboot/map.c |   20 ++++++++++++++------
 1 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/com32/mboot/map.c b/com32/mboot/map.c
index 267e50c..537741e 100644
--- a/com32/mboot/map.c
+++ b/com32/mboot/map.c
@@ -107,15 +107,15 @@ struct multiboot_header *map_image(void *ptr, size_t len)
     Elf32_Ehdr *eh = ptr;
     Elf32_Phdr *ph;
     Elf32_Shdr *sh;
-    unsigned int i;
+    unsigned int i, mbh_offset;
     uint32_t bad_flags;
 
     /*
      * Search for the multiboot header...
      */
     mbh_len = 0;
-    for (i = 0; i < MULTIBOOT_SEARCH; i += 4) {
-	mbh = (struct multiboot_header *)((char *)ptr + i);
+    for (mbh_offset = 0; mbh_offset < MULTIBOOT_SEARCH; mbh_offset += 4) {
+	mbh = (struct multiboot_header *)((char *)ptr + mbh_offset);
 	if (mbh->magic != MULTIBOOT_MAGIC)
 	    continue;
 	if (mbh->magic + mbh->flags + mbh->checksum)
@@ -127,7 +127,7 @@ struct multiboot_header *map_image(void *ptr, size_t len)
 	else
 	    mbh_len = 12;
 
-	if (i + mbh_len > len)
+	if (mbh_offset + mbh_len > len)
 	    mbh_len = 0;	/* Invalid... */
 	else
 	    break;		/* Found something... */
@@ -276,8 +276,16 @@ struct multiboot_header *map_image(void *ptr, size_t len)
 	regs.eip = mbh->entry_addr;
 
 	data_ptr = (char *)mbh - (mbh->header_addr - mbh->load_addr);
-	data_len = mbh->load_end_addr - mbh->load_addr;
-	bss_len = mbh->bss_end_addr - mbh->load_end_addr;
+	
+	if (mbh->load_end_addr)
+	    data_len = mbh->load_end_addr - mbh->load_addr;
+	else
+	    data_len = len - mbh_offset + (mbh->header_addr - mbh->load_addr);
+
+	if (mbh->bss_end_addr)
+	    bss_len = mbh->bss_end_addr - mbh->load_end_addr;
+	else
+	    bss_len = 0;
 
 	if (syslinux_memmap_type(amap, mbh->load_addr, data_len + bss_len)
 	    != SMT_FREE) {



More information about the Syslinux-commits mailing list