From b9615a08ff1f70d112b480673ebd5079468658a4 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 15 Jul 2010 23:03:19 +0800 Subject: [PATCH] Fixing binary loader bugs relating to page sizes --- Kernel/bin/elf.c | 17 ++++++++++------- Kernel/binary.c | 31 ++++++++++++++++++++++++++----- Kernel/modules.c | 14 -------------- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/Kernel/bin/elf.c b/Kernel/bin/elf.c index 731d1514..4bf15fa2 100644 --- a/Kernel/bin/elf.c +++ b/Kernel/bin/elf.c @@ -2,7 +2,7 @@ * Acess v0.1 * ELF Executable Loader Code */ -#define DEBUG 0 +#define DEBUG 1 #include #include #include "elf.h" @@ -35,7 +35,7 @@ tBinary *Elf_Load(int fp) int iPageCount; int count; - ENTER("ifp", fp); + ENTER("xfp", fp); // Read ELF Header VFS_Read(fp, sizeof(hdr), &hdr); @@ -126,13 +126,15 @@ tBinary *Elf_Load(int fp) LOG("phtab[%i] = {VAddr:0x%x,Offset:0x%x,FileSize:0x%x}", i, phtab[i].VAddr, phtab[i].Offset, phtab[i].FileSize); - if( (phtab[i].FileSize & 0xFFF) < 0x1000 - (phtab[i].VAddr & 0xFFF) ) - lastSize = phtab[i].FileSize; - else + //if( (phtab[i].FileSize & 0xFFF) < 0x1000 - (phtab[i].VAddr & 0xFFF) ) + // lastSize = phtab[i].FileSize; + //else lastSize = (phtab[i].FileSize & 0xFFF) + (phtab[i].VAddr & 0xFFF); - lastSize &= 0xFFF; + //lastSize &= 0xFFF; + + //LOG("lastSize = 0x%x", lastSize); - LOG("lastSize = 0x%x", lastSize); + lastSize = phtab[i].FileSize; // Get Pages count = ( (phtab[i].VAddr&0xFFF) + phtab[i].FileSize + 0xFFF) >> 12; @@ -152,6 +154,7 @@ tBinary *Elf_Load(int fp) ret->Pages[j+k].Size = 4096; LOG("ret->Pages[%i].Size = 0x%x", j+k, ret->Pages[j+k].Size); ret->Pages[j+k].Flags = 0; + lastSize -= ret->Pages[j+k].Size; } count = (phtab[i].MemSize + 0xFFF) >> 12; for(;kNumPages); // Read Data - for(i=0;iNumPages;i++) + for(i = 0; i < pBinary->NumPages; i ++) { Uint dest; tPAddr paddr; @@ -461,12 +460,34 @@ tBinary *Binary_DoLoad(char *truePath) else { VFS_Seek( fp, pBinary->Pages[i].Physical, 1 ); - if(pBinary->Pages[i].Size != 0x1000) { + // If the address is not aligned, or the page is not full + // sized, copy part of it + if( (dest & 0xFFF) > 0 || pBinary->Pages[i].Size < 0x1000) + { + // Validate the size to prevent Kernel page faults + // Clips to one page and prints a warning + if( pBinary->Pages[i].Size + (dest & 0xFFF) > 0x1000) { + Log_Warning("Binary", "Loader error: Page %i (%p) of '%s' is %i bytes (> 4096)", + i, pBinary->Pages[i].Virtual, truePath, + (dest&0xFFF) + pBinary->Pages[i].Size); + pBinary->Pages[i].Size = 0x1000 - (dest & 0xFFF); + } LOG("%i - 0x%llx - 0x%x bytes", i, pBinary->Pages[i].Physical, pBinary->Pages[i].Size); - memset( (void*)dest, 0, 0x1000 -(dest&0xFFF) ); + // Zero from `dest` to the end of the page + memset( (void*)dest, 0, 0x1000 - (dest&0xFFF) ); + // Read in the data VFS_Read( fp, pBinary->Pages[i].Size, (void*)dest ); - } else { + } + // Full page + else + { + // Check if the page is oversized + if(pBinary->Pages[i].Size > 0x1000) + Log_Warning("Binary", "Loader error - Page %i (%p) of '%s' is %i bytes (> 4096)", + i, pBinary->Pages[i].Virtual, truePath, + pBinary->Pages[i].Size); + // Read data LOG("%i - 0x%x", i, pBinary->Pages[i].Physical); VFS_Read( fp, 0x1000, (void*)dest ); } diff --git a/Kernel/modules.c b/Kernel/modules.c index c9f3a70a..9f6d3c54 100644 --- a/Kernel/modules.c +++ b/Kernel/modules.c @@ -349,20 +349,6 @@ int Module_LoadFile(char *Path, char *ArgString) return 0; } - // Check magic number - if(info->Magic != MODULE_MAGIC) - { - Log_Warning("Module", "Module's magic value is invalid (0x%x != 0x%x)", info->Magic, MODULE_MAGIC); - return 0; - } - - // Check Architecture - if(info->Arch != MODULE_ARCH_ID) - { - Log_Warning("Module", "Module is for a different architecture"); - return 0; - } - #if 1 if( Module_int_Initialise( info, ArgString ) ) { -- 2.20.1